From 3bf745c15538614920988b82dba32e8c7bf7c3d6 Mon Sep 17 00:00:00 2001 From: tutugordillo Date: Tue, 26 Nov 2024 14:56:40 +0100 Subject: [PATCH] adding new structure --- .../abi_decode_dynamic_array.sol | 7 + ...i_decode_dynamic_array_standard_input.json | 34 + .../abi_decode_fixed_arrays.sol | 8 + ...bi_decode_fixed_arrays_standard_input.json | 97 +++ .../abi_decode_static_array.sol | 11 + ...bi_decode_static_array_standard_input.json | 88 +++ .../abi_decode_static_array_v2.sol | 14 + ...decode_static_array_v2_standard_input.json | 79 ++ .../abi_decode_trivial.sol | 7 + .../abi_decode_trivial_standard_input.json | 64 ++ .../abi_decode_v2.sol | 21 + .../abi_decode_v2_standard_input.json | 103 +++ .../abi_decode_v2_calldata.sol | 15 + ...abi_decode_v2_calldata_standard_input.json | 112 +++ .../abi_decode_v2_storage.sol | 26 + .../abi_decode_v2_storage_standard_input.json | 73 ++ .../abiEncoderV1_abi_encode/abi_encode.sol | 35 + .../abi_encode_standard_input.json | 100 +++ .../abi_encode_call.sol | 25 + .../abi_encode_call_standard_input.json | 94 +++ .../abi_encode_calldata_slice.sol | 68 ++ ..._encode_calldata_slice_standard_input.json | 115 +++ .../abi_encode_decode_simple.sol | 8 + ...i_encode_decode_simple_standard_input.json | 49 ++ .../abi_encode_empty_string.sol | 34 + ...bi_encode_empty_string_standard_input.json | 67 ++ .../abi_encode_rational.sol | 8 + .../abi_encode_rational_standard_input.json | 52 ++ .../bool_out_of_bounds.sol | 12 + .../bool_out_of_bounds_standard_input.json | 58 ++ .../abiEncoderV1_byte_arrays/byte_arrays.sol | 14 + .../byte_arrays_standard_input.json | 43 ++ .../calldata_arrays_too_large.sol | 7 + ...ldata_arrays_too_large_standard_input.json | 85 ++ .../calldata_bytes_bytes32_arrays.sol | 14 + ...a_bytes_bytes32_arrays_standard_input.json | 106 +++ .../abiEncoderV1_cleanup_cleanup/cleanup.sol | 18 + .../cleanup_standard_input.json | 34 + .../decode_slice.sol | 9 + .../decode_slice_standard_input.json | 82 ++ .../dynamic_arrays.sol | 8 + .../dynamic_arrays_standard_input.json | 40 + .../dynamic_memory_copy.sol | 26 + .../dynamic_memory_copy_standard_input.json | 91 +++ .../abiEncoderV1_enums/enums.sol | 15 + .../enums_standard_input.json | 70 ++ ...emory_dynamic_array_and_calldata_bytes.sol | 16 + ...ray_and_calldata_bytes_standard_input.json | 109 +++ .../memory_params_in_external_function.sol | 16 + ...s_in_external_function_standard_input.json | 55 ++ ...turn_dynamic_types_cross_call_advanced.sol | 17 + ...es_cross_call_advanced_standard_input.json | 76 ++ ...ynamic_types_cross_call_out_of_range_1.sol | 19 + ...ss_call_out_of_range_1_standard_input.json | 46 ++ ...ynamic_types_cross_call_out_of_range_2.sol | 19 + ...ss_call_out_of_range_2_standard_input.json | 37 + ...return_dynamic_types_cross_call_simple.sol | 12 + ...ypes_cross_call_simple_standard_input.json | 61 ++ .../struct_storage_ptr.sol | 29 + .../struct_storage_ptr_standard_input.json | 34 + .../abi_encode_calldata_slice.sol | 69 ++ ..._encode_calldata_slice_standard_input.json | 157 ++++ .../abi_encode_empty_string_v2.sol | 12 + ...encode_empty_string_v2_standard_input.json | 163 ++++ .../abi_encode_rational_v2.sol | 11 + ...abi_encode_rational_v2_standard_input.json | 37 + .../abi_encode_v2.sol | 55 ++ .../abi_encode_v2_standard_input.json | 121 +++ ...2_in_function_inherited_in_v1_contract.sol | 38 + ...herited_in_v1_contract_standard_input.json | 109 +++ ...ode_v2_in_modifier_used_in_v1_contract.sol | 43 ++ ...er_used_in_v1_contract_standard_input.json | 160 ++++ ...overflow_with_static_array_cleanup_bug.sol | 17 + ...atic_array_cleanup_bug_standard_input.json | 151 ++++ .../bool_out_of_bounds.sol | 10 + .../bool_out_of_bounds_standard_input.json | 73 ++ .../abiEncoderV2_byte_arrays/byte_arrays.sol | 16 + .../byte_arrays_standard_input.json | 46 ++ .../calldata_array.sol | 25 + .../calldata_array_standard_input.json | 103 +++ .../calldata_array_dynamic.sol | 33 + ...calldata_array_dynamic_standard_input.json | 115 +++ .../calldata_array_dynamic_index_access.sol | 34 + ...y_dynamic_index_access_standard_input.json | 61 ++ .../calldata_array_dynamic_static_dynamic.sol | 49 ++ ...dynamic_static_dynamic_standard_input.json | 88 +++ ...lldata_array_dynamic_static_in_library.sol | 17 + ...amic_static_in_library_standard_input.json | 70 ++ ...data_array_dynamic_static_short_decode.sol | 11 + ...ic_static_short_decode_standard_input.json | 85 ++ ...ta_array_dynamic_static_short_reencode.sol | 13 + ..._static_short_reencode_standard_input.json | 154 ++++ .../calldata_array_function_types.sol | 30 + ...a_array_function_types_standard_input.json | 130 ++++ .../calldata_array_multi_dynamic.sol | 31 + ...ta_array_multi_dynamic_standard_input.json | 142 ++++ .../calldata_array_short.sol | 11 + .../calldata_array_short_standard_input.json | 94 +++ .../calldata_array_short_no_revert_string.sol | 8 + ...short_no_revert_string_standard_input.json | 58 ++ .../calldata_array_static.sol | 25 + .../calldata_array_static_standard_input.json | 145 ++++ .../calldata_array_static_dynamic_static.sol | 49 ++ ..._static_dynamic_static_standard_input.json | 100 +++ .../calldata_array_static_index_access.sol | 25 + ...ay_static_index_access_standard_input.json | 127 +++ .../calldata_array_struct_dynamic.sol | 16 + ...a_array_struct_dynamic_standard_input.json | 55 ++ .../calldata_array_two_dynamic.sol | 20 + ...data_array_two_dynamic_standard_input.json | 124 +++ .../calldata_array_two_static.sol | 20 + ...ldata_array_two_static_standard_input.json | 79 ++ .../calldata_dynamic_array_to_memory.sol | 24 + ...ynamic_array_to_memory_standard_input.json | 76 ++ .../calldata_nested_array_reencode.sol | 36 + ..._nested_array_reencode_standard_input.json | 148 ++++ .../calldata_nested_array_static_reencode.sol | 25 + ..._array_static_reencode_standard_input.json | 43 ++ .../calldata_overlapped_dynamic_arrays.sol | 40 + ...rlapped_dynamic_arrays_standard_input.json | 97 +++ ...ldata_overlapped_nested_dynamic_arrays.sol | 34 + ..._nested_dynamic_arrays_standard_input.json | 64 ++ .../calldata_struct_array_reencode.sol | 53 ++ ..._struct_array_reencode_standard_input.json | 34 + .../calldata_struct_dynamic.sol | 18 + ...alldata_struct_dynamic_standard_input.json | 112 +++ .../calldata_struct_member_offset.sol | 23 + ...a_struct_member_offset_standard_input.json | 49 ++ .../calldata_struct_simple.sol | 18 + ...calldata_struct_simple_standard_input.json | 82 ++ ...dimensional_dynamic_array_index_access.sol | 40 + ...mic_array_index_access_standard_input.json | 106 +++ .../calldata_with_garbage.sol | 66 ++ .../calldata_with_garbage_standard_input.json | 52 ++ .../abiEncoderV2_cleanup_address/address.sol | 31 + .../address_standard_input.json | 46 ++ .../abiEncoderV2_cleanup_bool/bool.sol | 21 + .../bool_standard_input.json | 37 + .../abiEncoderV2_cleanup_bytesx/bytesx.sol | 115 +++ .../bytesx_standard_input.json | 43 ++ .../abiEncoderV2_cleanup_cleanup/cleanup.sol | 16 + .../cleanup_standard_input.json | 49 ++ .../dynamic_array.sol | 22 + .../dynamic_array_standard_input.json | 64 ++ .../function.sol | 28 + .../function_standard_input.json | 52 ++ .../abiEncoderV2_cleanup_intx/intx.sol | 155 ++++ .../intx_standard_input.json | 40 + .../reencoded_calldata_string.sol | 27 + ...ncoded_calldata_string_standard_input.json | 61 ++ .../simple_struct.sol | 24 + .../simple_struct_standard_input.json | 34 + .../static_array.sol | 23 + .../static_array_standard_input.json | 58 ++ .../abiEncoderV2_cleanup_uintx/uintx.sol | 115 +++ .../uintx_standard_input.json | 55 ++ .../dynamic_arrays.sol | 10 + .../dynamic_arrays_standard_input.json | 40 + .../dynamic_nested_arrays.sol | 30 + .../dynamic_nested_arrays_standard_input.json | 139 ++++ .../abiEncoderV2_enums/enums.sol | 13 + .../enums_standard_input.json | 91 +++ ...emory_dynamic_array_and_calldata_bytes.sol | 12 + ...ray_and_calldata_bytes_standard_input.json | 136 ++++ ...ynamic_array_and_calldata_static_array.sol | 17 + ..._calldata_static_array_standard_input.json | 118 +++ .../memory_params_in_external_function.sol | 18 + ...s_in_external_function_standard_input.json | 67 ++ .../storage_array_encoding.sol | 27 + ...storage_array_encoding_standard_input.json | 133 ++++ .../mediocre2_struct.sol | 12 + .../mediocre2_struct_standard_input.json | 52 ++ .../mediocre_struct.sol | 12 + .../mediocre_struct_standard_input.json | 43 ++ .../struct_function.sol | 14 + .../struct_function_standard_input.json | 37 + .../struct_short.sol | 11 + .../struct_short_standard_input.json | 49 ++ .../struct_simple.sol | 13 + .../struct_simple_standard_input.json | 34 + .../struct_validation.sol | 17 + .../struct_validation_standard_input.json | 40 + ...validation_function_type_inside_struct.sol | 15 + ...ion_type_inside_struct_standard_input.json | 46 ++ .../abi_decode_calldata.sol | 11 + .../abi_decode_calldata_standard_input.json | 55 ++ .../abi_decode_simple.sol | 7 + .../abi_decode_simple_standard_input.json | 73 ++ .../abi_decode_simple_storage.sol | 13 + ..._decode_simple_storage_standard_input.json | 79 ++ .../abi_encode_call.sol | 48 ++ .../abi_encode_call_standard_input.json | 67 ++ .../abi_encode_call_declaration.sol | 52 ++ ...ncode_call_declaration_standard_input.json | 85 ++ .../abi_encode_call_is_consistent.sol | 61 ++ ...ode_call_is_consistent_standard_input.json | 70 ++ .../abi_encode_call_memory.sol | 25 + ...abi_encode_call_memory_standard_input.json | 76 ++ .../abi_encode_call_special_args.sol | 46 ++ ...code_call_special_args_standard_input.json | 52 ++ .../abi_encode_call_uint_bytes.sol | 20 + ...encode_call_uint_bytes_standard_input.json | 46 ++ .../abi_encode_empty_string_v1.sol | 13 + ...encode_empty_string_v1_standard_input.json | 88 +++ .../abi_encode_with_selector.sol | 22 + ...i_encode_with_selector_standard_input.json | 58 ++ .../abi_encode_with_selectorv2.sol | 32 + ...encode_with_selectorv2_standard_input.json | 64 ++ .../abi_encode_with_signature.sol | 32 + ..._encode_with_signature_standard_input.json | 61 ++ .../abi_encode_with_signaturev2.sol | 41 + ...ncode_with_signaturev2_standard_input.json | 37 + .../contract_array.sol | 15 + .../contract_array_standard_input.json | 82 ++ .../contract_array_v2.sol | 18 + .../contract_array_v2_standard_input.json | 43 ++ .../offset_overflow_in_array_decoding.sol | 27 + ...flow_in_array_decoding_standard_input.json | 49 ++ .../offset_overflow_in_array_decoding_2.sol | 28 + ...ow_in_array_decoding_2_standard_input.json | 34 + .../offset_overflow_in_array_decoding_3.sol | 21 + ...ow_in_array_decoding_3_standard_input.json | 40 + .../accessor_for_const_state_variable.sol | 5 + ...r_const_state_variable_standard_input.json | 37 + .../accessor_for_state_variable.sol | 5 + ...sor_for_state_variable_standard_input.json | 34 + .../addmod_mulmod.sol | 11 + .../addmod_mulmod_standard_input.json | 37 + .../addmod_mulmod_zero.sol | 23 + .../addmod_mulmod_zero_standard_input.json | 55 ++ .../block_inside_unchecked.sol | 11 + ...block_inside_unchecked_standard_input.json | 40 + .../check_var_init.sol | 20 + .../check_var_init_standard_input.json | 58 ++ .../checked_add_v1.sol | 15 + .../checked_add_v1_standard_input.json | 49 ++ .../checked_add_v2.sol | 11 + .../checked_add_v2_standard_input.json | 46 ++ .../checked_called_by_unchecked.sol | 12 + ...ed_called_by_unchecked_standard_input.json | 67 ++ .../checked_modifier_called_by_unchecked.sol | 13 + ...er_called_by_unchecked_standard_input.json | 52 ++ .../divisiod_by_zero.sol | 14 + .../divisiod_by_zero_standard_input.json | 70 ++ .../exp_associativity.sol | 38 + .../exp_associativity_standard_input.json | 64 ++ .../arithmetics_signed_mod/signed_mod.sol | 21 + .../signed_mod_standard_input.json | 61 ++ .../unchecked_called_by_checked.sol | 15 + ...cked_called_by_checked_standard_input.json | 34 + .../unchecked_div_by_zero.sol | 20 + .../unchecked_div_by_zero_standard_input.json | 43 ++ .../array_2d_assignment.sol | 12 + .../array_2d_assignment_standard_input.json | 193 +++++ .../array_array_2d_new/array_2d_new.sol | 10 + .../array_2d_new_standard_input.json | 37 + .../array_3d_assignment.sol | 17 + .../array_3d_assignment_standard_input.json | 181 +++++ .../array_array_3d_new/array_3d_new.sol | 14 + .../array_3d_new_standard_input.json | 40 + .../array_function_pointers.sol | 27 + ...rray_function_pointers_standard_input.json | 157 ++++ .../array_2d_zeroed_memory_index_access.sol | 22 + ...ed_memory_index_access_standard_input.json | 37 + .../array_array_static.sol | 20 + .../array_array_static_standard_input.json | 43 ++ ...eturn_param_zeroed_memory_index_access.sol | 15 + ...ed_memory_index_access_standard_input.json | 46 ++ ...rray_static_zeroed_memory_index_access.sol | 17 + ...ed_memory_index_access_standard_input.json | 34 + .../array_zeroed_memory_index_access.sol | 20 + ...ed_memory_index_access_standard_input.json | 40 + .../array_memory_as_parameter.sol | 24 + ...ay_memory_as_parameter_standard_input.json | 163 ++++ .../array_memory_create.sol | 11 + .../array_memory_create_standard_input.json | 184 +++++ .../array_memory_index_access.sol | 36 + ...ay_memory_index_access_standard_input.json | 82 ++ .../array_push_return_reference.sol | 23 + ..._push_return_reference_standard_input.json | 67 ++ .../array_push_with_arg.sol | 23 + .../array_push_with_arg_standard_input.json | 73 ++ .../array_storage_index_access.sol | 53 ++ ...y_storage_index_access_standard_input.json | 118 +++ .../array_storage_index_boundary_test.sol | 27 + ...ge_index_boundary_test_standard_input.json | 190 +++++ .../array_storage_index_zeroed_test.sol | 69 ++ ...rage_index_zeroed_test_standard_input.json | 124 +++ .../array_storage_length_access.sol | 22 + ..._storage_length_access_standard_input.json | 100 +++ .../array_storage_pop_zero_length.sol | 10 + ...torage_pop_zero_length_standard_input.json | 208 +++++ .../array_storage_push_empty.sol | 25 + ...ray_storage_push_empty_standard_input.json | 178 +++++ ...rray_storage_push_empty_length_address.sol | 33 + ...h_empty_length_address_standard_input.json | 109 +++ .../array_storage_push_pop.sol | 27 + ...array_storage_push_pop_standard_input.json | 223 ++++++ .../arrays_complex_from_and_to_storage.sol | 21 + ...ex_from_and_to_storage_standard_input.json | 112 +++ .../byte_array_storage_layout.sol | 55 ++ ...e_array_storage_layout_standard_input.json | 115 +++ .../byte_array_transitional_2.sol | 22 + ...e_array_transitional_2_standard_input.json | 172 +++++ .../bytes_length_member.sol | 19 + .../bytes_length_member_standard_input.json | 238 ++++++ .../bytes_to_fixed_bytes_cleanup.sol | 24 + ...to_fixed_bytes_cleanup_standard_input.json | 136 ++++ .../bytes_to_fixed_bytes_simple.sol | 26 + ..._to_fixed_bytes_simple_standard_input.json | 199 +++++ .../bytes_to_fixed_bytes_too_long.sol | 21 + ...o_fixed_bytes_too_long_standard_input.json | 34 + .../array_calldata_array/calldata_array.sol | 15 + .../calldata_array_standard_input.json | 151 ++++ ...ta_array_as_argument_internal_function.sol | 17 + ...ment_internal_function_standard_input.json | 58 ++ .../calldata_array_dynamic_invalid.sol | 20 + ..._array_dynamic_invalid_standard_input.json | 85 ++ ...ta_array_dynamic_invalid_static_middle.sol | 29 + ..._invalid_static_middle_standard_input.json | 61 ++ .../calldata_array_of_struct.sol | 23 + ...lldata_array_of_struct_standard_input.json | 76 ++ .../calldata_array_two_dimensional.sol | 36 + ..._array_two_dimensional_standard_input.json | 148 ++++ .../calldata_array_two_dimensional_1.sol | 36 + ...rray_two_dimensional_1_standard_input.json | 64 ++ .../calldata_bytes_array_bounds.sol | 10 + ...ata_bytes_array_bounds_standard_input.json | 70 ++ .../calldata_slice_access.sol | 44 ++ .../calldata_slice_access_standard_input.json | 220 ++++++ .../bytes_concat_2_args.sol | 28 + .../bytes_concat_2_args_standard_input.json | 46 ++ .../bytes_concat_3_args.sol | 8 + .../bytes_concat_3_args_standard_input.json | 43 ++ .../bytes_concat_as_argument.sol | 16 + ...tes_concat_as_argument_standard_input.json | 52 ++ .../bytes_concat_different_types.sol | 73 ++ ...concat_different_types_standard_input.json | 37 + .../bytes_concat_empty_argument_list.sol | 7 + ...at_empty_argument_list_standard_input.json | 34 + .../bytes_concat_empty_strings.sol | 24 + ...s_concat_empty_strings_standard_input.json | 49 ++ .../bytes_concat_nested.sol | 7 + .../bytes_concat_nested_standard_input.json | 40 + .../constant_var_as_array_length.sol | 19 + ...nt_var_as_array_length_standard_input.json | 232 ++++++ .../array_copy_calldata_storage.sol | 26 + ..._copy_calldata_storage_standard_input.json | 202 +++++ .../array_copy_cleanup_uint128.sol | 26 + ...y_copy_cleanup_uint128_standard_input.json | 34 + .../array_copy_cleanup_uint40.sol | 51 ++ ...ay_copy_cleanup_uint40_standard_input.json | 211 +++++ .../array_copy_clear_storage.sol | 18 + ...ray_copy_clear_storage_standard_input.json | 259 +++++++ .../array_copy_clear_storage_packed.sol | 50 ++ ...y_clear_storage_packed_standard_input.json | 97 +++ .../array_copy_different_packing.sol | 23 + ...copy_different_packing_standard_input.json | 145 ++++ .../array_copy_including_array.sol | 46 ++ ...y_copy_including_array_standard_input.json | 61 ++ .../array_copy_memory_to_storage.sol | 28 + ...copy_memory_to_storage_standard_input.json | 175 +++++ .../array_copy_nested_array.sol | 17 + ...rray_copy_nested_array_standard_input.json | 118 +++ .../array_copy_storage_abi_signed.sol | 19 + ...opy_storage_abi_signed_standard_input.json | 52 ++ ...ay_copy_storage_storage_different_base.sol | 22 + ...storage_different_base_standard_input.json | 280 +++++++ ..._storage_storage_different_base_nested.sol | 26 + ..._different_base_nested_standard_input.json | 214 ++++++ .../array_copy_storage_storage_dyn_dyn.sol | 25 + ...torage_storage_dyn_dyn_standard_input.json | 298 +++++++ ...y_copy_storage_storage_dynamic_dynamic.sol | 22 + ...torage_dynamic_dynamic_standard_input.json | 286 +++++++ ...ay_copy_storage_storage_static_dynamic.sol | 16 + ...storage_static_dynamic_standard_input.json | 304 ++++++++ ...ray_copy_storage_storage_static_simple.sol | 15 + ..._storage_static_simple_standard_input.json | 256 +++++++ ...ray_copy_storage_storage_static_static.sol | 19 + ..._storage_static_static_standard_input.json | 109 +++ .../array_copy_storage_storage_struct.sol | 23 + ...storage_storage_struct_standard_input.json | 274 +++++++ .../array_copy_storage_to_memory.sol | 10 + ...copy_storage_to_memory_standard_input.json | 127 +++ .../array_copy_storage_to_memory_nested.sol | 20 + ...orage_to_memory_nested_standard_input.json | 277 +++++++ .../array_copy_target_leftover.sol | 22 + ...y_copy_target_leftover_standard_input.json | 58 ++ .../array_copy_target_leftover2.sol | 24 + ..._copy_target_leftover2_standard_input.json | 205 +++++ .../array_copy_target_simple.sol | 23 + ...ray_copy_target_simple_standard_input.json | 157 ++++ .../array_copy_target_simple_2.sol | 23 + ...y_copy_target_simple_2_standard_input.json | 124 +++ .../array_elements_to_mapping.sol | 60 ++ ...ay_elements_to_mapping_standard_input.json | 172 +++++ .../array_nested_calldata_to_memory.sol | 36 + ...ted_calldata_to_memory_standard_input.json | 289 +++++++ .../array_nested_calldata_to_storage.sol | 47 ++ ...ed_calldata_to_storage_standard_input.json | 184 +++++ .../array_nested_memory_to_storage.sol | 49 ++ ...sted_memory_to_storage_standard_input.json | 262 +++++++ .../array_nested_storage_to_memory.sol | 44 ++ ...sted_storage_to_memory_standard_input.json | 64 ++ ...on_external_storage_to_storage_dynamic.sol | 51 ++ ...age_to_storage_dynamic_standard_input.json | 37 + ...o_storage_dynamic_different_mutability.sol | 55 ++ ...c_different_mutability_standard_input.json | 76 ++ .../array_of_struct_calldata_to_memory.sol | 20 + ...uct_calldata_to_memory_standard_input.json | 196 +++++ .../array_of_struct_calldata_to_storage.sol | 20 + ...ct_calldata_to_storage_standard_input.json | 151 ++++ .../array_of_struct_memory_to_storage.sol | 22 + ...ruct_memory_to_storage_standard_input.json | 217 ++++++ ...s_containing_arrays_calldata_to_memory.sol | 21 + ...ays_calldata_to_memory_standard_input.json | 253 ++++++ ..._containing_arrays_calldata_to_storage.sol | 26 + ...ys_calldata_to_storage_standard_input.json | 238 ++++++ ...ts_containing_arrays_memory_to_storage.sol | 29 + ...rays_memory_to_storage_standard_input.json | 178 +++++ .../array_storage_multi_items_per_slot.sol | 17 + ...e_multi_items_per_slot_standard_input.json | 133 ++++ .../array_to_mapping.sol | 44 ++ .../array_to_mapping_standard_input.json | 121 +++ .../arrays_from_and_to_storage.sol | 19 + ...ys_from_and_to_storage_standard_input.json | 235 ++++++ .../bytes_calldata_to_string_calldata.sol | 7 + ...ata_to_string_calldata_standard_input.json | 295 +++++++ .../bytes_inside_mappings.sol | 21 + .../bytes_inside_mappings_standard_input.json | 232 ++++++ .../bytes_memory_to_storage.sol | 10 + ...ytes_memory_to_storage_standard_input.json | 190 +++++ .../bytes_storage_to_memory.sol | 9 + ...ytes_storage_to_memory_standard_input.json | 142 ++++ .../bytes_storage_to_storage.sol | 41 + ...tes_storage_to_storage_standard_input.json | 70 ++ ..._1d_array_into_2d_memory_array_element.sol | 37 + ...d_memory_array_element_standard_input.json | 154 ++++ .../calldata_2d_bytes_to_memory.sol | 12 + ...ata_2d_bytes_to_memory_standard_input.json | 181 +++++ .../calldata_2d_bytes_to_memory_2.sol | 16 + ...a_2d_bytes_to_memory_2_standard_input.json | 46 ++ .../calldata_array_dynamic_to_storage.sol | 14 + ...ray_dynamic_to_storage_standard_input.json | 103 +++ .../calldata_array_of_struct_to_memory.sol | 24 + ...ay_of_struct_to_memory_standard_input.json | 43 ++ .../calldata_array_static_to_memory.sol | 8 + ...array_static_to_memory_standard_input.json | 169 ++++ .../calldata_array_to_mapping.sol | 17 + ...ldata_array_to_mapping_standard_input.json | 187 +++++ .../calldata_bytes_array_to_memory.sol | 18 + ..._bytes_array_to_memory_standard_input.json | 247 ++++++ .../calldata_bytes_to_storage.sol | 9 + ...ldata_bytes_to_storage_standard_input.json | 148 ++++ .../calldata_dyn_2d_bytes_to_memory.sol | 9 + ...dyn_2d_bytes_to_memory_standard_input.json | 229 ++++++ .../calldata_dynamic_array_to_memory.sol | 14 + ...ynamic_array_to_memory_standard_input.json | 112 +++ .../calldata_nested_array_copy_to_memory.sol | 12 + ...d_array_copy_to_memory_standard_input.json | 163 ++++ .../calldata_to_storage_different_base.sol | 11 + ...storage_different_base_standard_input.json | 220 ++++++ ...nup_during_multi_element_per_slot_copy.sol | 25 + ..._element_per_slot_copy_standard_input.json | 301 ++++++++ .../copy_byte_array_in_struct_to_storage.sol | 46 ++ ...y_in_struct_to_storage_standard_input.json | 88 +++ .../copy_byte_array_to_storage.sol | 51 ++ ..._byte_array_to_storage_standard_input.json | 208 +++++ .../copy_function_internal_storage_array.sol | 20 + ...internal_storage_array_standard_input.json | 115 +++ ...opy_internal_function_array_to_storage.sol | 23 + ...ction_array_to_storage_standard_input.json | 73 ++ .../copy_removes_bytes_data.sol | 15 + ...opy_removes_bytes_data_standard_input.json | 271 +++++++ .../copying_bytes_multiassign.sol | 30 + ...ying_bytes_multiassign_standard_input.json | 199 +++++ .../dirty_memory_bytes_to_storage_copy.sol | 19 + ..._bytes_to_storage_copy_standard_input.json | 268 +++++++ .../dirty_memory_bytes_to_storage_copy_ir.sol | 18 + ...tes_to_storage_copy_ir_standard_input.json | 100 +++ ...d_array_of_structs_calldata_to_storage.sol | 38 + ...ts_calldata_to_storage_standard_input.json | 283 +++++++ ...ted_array_of_structs_memory_to_storage.sol | 38 + ...ucts_memory_to_storage_standard_input.json | 91 +++ .../empty_bytes_copy.sol | 28 + .../empty_bytes_copy_standard_input.json | 223 ++++++ .../function_type_array_to_storage.sol | 56 ++ ..._type_array_to_storage_standard_input.json | 130 ++++ .../memory_dyn_2d_bytes_to_storage.sol | 23 + ...yn_2d_bytes_to_storage_standard_input.json | 49 ++ .../memory_to_storage_different_base.sol | 15 + ...storage_different_base_standard_input.json | 139 ++++ ...ested_array_element_calldata_to_memory.sol | 40 + ...ent_calldata_to_memory_standard_input.json | 40 + ...sted_array_element_calldata_to_storage.sol | 29 + ...nt_calldata_to_storage_standard_input.json | 307 ++++++++ .../nested_array_element_memory_to_memory.sol | 40 + ...ement_memory_to_memory_standard_input.json | 226 ++++++ ...nested_array_element_memory_to_storage.sol | 29 + ...ment_memory_to_storage_standard_input.json | 166 ++++ ...nested_array_element_storage_to_memory.sol | 70 ++ ...ment_storage_to_memory_standard_input.json | 106 +++ ...ested_array_element_storage_to_storage.sol | 84 ++ ...ent_storage_to_storage_standard_input.json | 67 ++ ...ed_array_of_structs_calldata_to_memory.sol | 24 + ...cts_calldata_to_memory_standard_input.json | 94 +++ ...d_array_of_structs_calldata_to_storage.sol | 36 + ...ts_calldata_to_storage_standard_input.json | 244 ++++++ ...sted_array_of_structs_memory_to_memory.sol | 24 + ...ructs_memory_to_memory_standard_input.json | 241 ++++++ ...ted_array_of_structs_memory_to_storage.sol | 36 + ...ucts_memory_to_storage_standard_input.json | 292 +++++++ ...ed_array_of_structs_storage_to_storage.sol | 69 ++ ...cts_storage_to_storage_standard_input.json | 79 ++ ...th_nested_array_from_storage_to_memory.sol | 44 ++ ...from_storage_to_memory_standard_input.json | 250 ++++++ ...amic_array_element_calldata_to_storage.sol | 36 + ...nt_calldata_to_storage_standard_input.json | 85 ++ .../storage_memory_nested.sol | 22 + .../storage_memory_nested_standard_input.json | 310 ++++++++ .../storage_memory_nested_bytes.sol | 16 + ...ge_memory_nested_bytes_standard_input.json | 193 +++++ .../storage_memory_nested_from_pointer.sol | 23 + ...ry_nested_from_pointer_standard_input.json | 55 ++ .../storage_memory_nested_struct.sol | 29 + ...e_memory_nested_struct_standard_input.json | 160 ++++ .../storage_memory_packed.sol | 13 + .../storage_memory_packed_standard_input.json | 136 ++++ .../storage_memory_packed_dyn.sol | 18 + ...rage_memory_packed_dyn_standard_input.json | 265 +++++++ .../string_calldata_to_bytes_calldata.sol | 7 + ...data_to_bytes_calldata_standard_input.json | 82 ++ .../create_dynamic_array_with_zero_length.sol | 8 + ...array_with_zero_length_standard_input.json | 94 +++ .../create_memory_array.sol | 23 + .../create_memory_array_standard_input.json | 169 ++++ .../create_memory_array_too_large.sol | 24 + ...memory_array_too_large_standard_input.json | 217 ++++++ .../create_memory_byte_array.sol | 10 + ...eate_memory_byte_array_standard_input.json | 55 ++ .../create_multiple_dynamic_arrays.sol | 33 + ...ultiple_dynamic_arrays_standard_input.json | 46 ++ .../bytes_delete_element.sol | 21 + .../bytes_delete_element_standard_input.json | 46 ++ .../delete_bytes_array.sol | 34 + .../delete_bytes_array_standard_input.json | 55 ++ .../delete_memory_array.sol | 14 + .../delete_memory_array_standard_input.json | 49 ++ .../delete_on_array_of_structs.sol | 19 + ...te_on_array_of_structs_standard_input.json | 52 ++ .../delete_removes_bytes_data.sol | 10 + ...ete_removes_bytes_data_standard_input.json | 37 + .../delete_storage_array.sol | 37 + .../delete_storage_array_standard_input.json | 43 ++ .../delete_storage_array_packed.sol | 19 + ...e_storage_array_packed_standard_input.json | 40 + .../memory_arrays_delete.sol | 13 + .../memory_arrays_delete_standard_input.json | 34 + .../dynamic_array_cleanup.sol | 27 + .../dynamic_array_cleanup_standard_input.json | 196 +++++ .../dynamic_arrays_in_storage.sol | 55 ++ ...amic_arrays_in_storage_standard_input.json | 214 ++++++ .../dynamic_multi_array_cleanup.sol | 24 + ...ic_multi_array_cleanup_standard_input.json | 43 ++ .../dynamic_out_of_bounds_array_access.sol | 31 + ...of_bounds_array_access_standard_input.json | 211 +++++ .../evm_exceptions_out_of_band_access.sol | 18 + ...ons_out_of_band_access_standard_input.json | 88 +++ .../external_array_args.sol | 10 + .../external_array_args_standard_input.json | 202 +++++ .../fixed_array_cleanup.sol | 21 + .../fixed_array_cleanup_standard_input.json | 52 ++ .../fixed_arrays_as_return_type.sol | 26 + ..._arrays_as_return_type_standard_input.json | 145 ++++ .../fixed_arrays_in_constructors.sol | 19 + ...arrays_in_constructors_standard_input.json | 187 +++++ .../fixed_arrays_in_storage.sol | 45 ++ ...ixed_arrays_in_storage_standard_input.json | 133 ++++ .../fixed_bytes_length_access.sol | 9 + ...ed_bytes_length_access_standard_input.json | 175 +++++ .../fixed_out_of_bounds_array_access.sol | 25 + ...of_bounds_array_access_standard_input.json | 142 ++++ .../function_array_cross_calls.sol | 50 ++ ...tion_array_cross_calls_standard_input.json | 139 ++++ .../function_memory_array.sol | 39 + .../function_memory_array_standard_input.json | 130 ++++ .../arrays_complex_memory_index_access.sol | 11 + ...ex_memory_index_access_standard_input.json | 40 + .../bytes_index_access.sol | 25 + .../bytes_index_access_standard_input.json | 55 ++ .../bytes_index_access_memory.sol | 15 + ...es_index_access_memory_standard_input.json | 37 + .../bytes_memory_index_access.sol | 11 + ...es_memory_index_access_standard_input.json | 58 ++ .../fixed_bytes_index_access.sol | 17 + ...xed_bytes_index_access_standard_input.json | 34 + .../index_access.sol | 18 + .../index_access_standard_input.json | 46 ++ .../inline_array_index_access_ints.sol | 7 + ...rray_index_access_ints_standard_input.json | 61 ++ .../inline_array_index_access_strings.sol | 14 + ...y_index_access_strings_standard_input.json | 49 ++ ...mory_arrays_dynamic_index_access_write.sol | 19 + ...mic_index_access_write_standard_input.json | 43 ++ .../memory_arrays_index_access_write.sol | 14 + ...ays_index_access_write_standard_input.json | 52 ++ .../inline_array_return.sol | 14 + .../inline_array_return_standard_input.json | 235 ++++++ .../inline_array_singleton.sol | 8 + ...inline_array_singleton_standard_input.json | 103 +++ ...rray_storage_to_memory_conversion_ints.sol | 10 + ...memory_conversion_ints_standard_input.json | 226 ++++++ ...y_storage_to_memory_conversion_strings.sol | 11 + ...ory_conversion_strings_standard_input.json | 166 ++++ .../inline_array_strings_from_document.sol | 11 + ..._strings_from_document_standard_input.json | 154 ++++ ...nvalid_encoding_for_storage_byte_array.sol | 95 +++ ...for_storage_byte_array_standard_input.json | 121 +++ .../semanticTests/array_memory/memory.sol | 14 + .../array_memory/memory_standard_input.json | 229 ++++++ .../memory_arrays_of_various_sizes.sol | 16 + ...rrays_of_various_sizes_standard_input.json | 160 ++++ .../array_pop_array_pop/array_pop.sol | 15 + .../array_pop_standard_input.json | 43 ++ .../array_pop_array_transition.sol | 29 + ...y_pop_array_transition_standard_input.json | 49 ++ .../array_pop_empty_exception.sol | 10 + ...ay_pop_empty_exception_standard_input.json | 64 ++ .../array_pop_isolated.sol | 12 + .../array_pop_isolated_standard_input.json | 37 + .../array_pop_storage_empty.sol | 10 + ...rray_pop_storage_empty_standard_input.json | 46 ++ .../array_pop_uint16_transition.sol | 24 + ..._pop_uint16_transition_standard_input.json | 52 ++ .../array_pop_uint24_transition.sol | 24 + ..._pop_uint24_transition_standard_input.json | 67 ++ .../byte_array_pop.sol | 16 + .../byte_array_pop_standard_input.json | 40 + .../byte_array_pop_copy_long.sol | 14 + ...te_array_pop_copy_long_standard_input.json | 79 ++ .../byte_array_pop_empty_exception.sol | 13 + ...ay_pop_empty_exception_standard_input.json | 76 ++ .../byte_array_pop_isolated.sol | 12 + ...yte_array_pop_isolated_standard_input.json | 73 ++ .../byte_array_pop_long_storage_empty.sol | 22 + ...pop_long_storage_empty_standard_input.json | 55 ++ ...ray_pop_long_storage_empty_garbage_ref.sol | 21 + ...rage_empty_garbage_ref_standard_input.json | 58 ++ .../byte_array_pop_masking_long.sol | 14 + ...array_pop_masking_long_standard_input.json | 70 ++ .../byte_array_pop_storage_empty.sol | 14 + ...rray_pop_storage_empty_standard_input.json | 61 ++ .../array_pop_parenthesized/parenthesized.sol | 10 + .../parenthesized_standard_input.json | 34 + .../array_push_array_push/array_push.sol | 21 + .../array_push_standard_input.json | 37 + .../array_push_nested.sol | 15 + .../array_push_nested_standard_input.json | 40 + .../array_push_nested_from_calldata.sol | 17 + ...h_nested_from_calldata_standard_input.json | 61 ++ .../array_push_nested_from_memory.sol | 17 + ...ush_nested_from_memory_standard_input.json | 55 ++ .../array_push_packed_array.sol | 18 + ...rray_push_packed_array_standard_input.json | 43 ++ .../array_push_struct.sol | 25 + .../array_push_struct_standard_input.json | 70 ++ .../array_push_struct_from_calldata.sol | 21 + ...h_struct_from_calldata_standard_input.json | 64 ++ .../byte_array_push.sol | 17 + .../byte_array_push_standard_input.json | 67 ++ .../byte_array_push_transition.sol | 20 + ..._array_push_transition_standard_input.json | 49 ++ .../nested_bytes_push.sol | 18 + .../nested_bytes_push_standard_input.json | 58 ++ .../push_no_args_1d.sol | 32 + .../push_no_args_1d_standard_input.json | 34 + .../push_no_args_2d.sol | 45 ++ .../push_no_args_2d_standard_input.json | 73 ++ .../push_no_args_bytes.sol | 31 + .../push_no_args_bytes_standard_input.json | 46 ++ .../push_no_args_struct.sol | 44 ++ .../push_no_args_struct_standard_input.json | 52 ++ .../array_reusing_memory/reusing_memory.sol | 32 + .../reusing_memory_standard_input.json | 49 ++ .../short_fixed_array_cleanup.sol | 15 + ...rt_fixed_array_cleanup_standard_input.json | 127 +++ .../array_calldata_assignment.sol | 8 + ...ay_calldata_assignment_standard_input.json | 40 + ...calldata_as_argument_of_external_calls.sol | 37 + ...ment_of_external_calls_standard_input.json | 43 ++ .../array_slice_calldata_to_calldata.sol | 25 + ...e_calldata_to_calldata_standard_input.json | 46 ++ .../array_slice_calldata_to_memory.sol | 27 + ...ice_calldata_to_memory_standard_input.json | 34 + .../array_slice_calldata_to_storage.sol | 14 + ...ce_calldata_to_storage_standard_input.json | 37 + .../storage_array_ref.sol | 57 ++ .../storage_array_ref_standard_input.json | 106 +++ .../string_allocation_bug.sol | 20 + .../string_allocation_bug_standard_input.json | 79 ++ .../string_bytes_conversion.sol | 17 + ...tring_bytes_conversion_standard_input.json | 205 +++++ ...string_literal_assign_to_storage_bytes.sol | 20 + ...ssign_to_storage_bytes_standard_input.json | 91 +++ .../strings_in_struct.sol | 35 + .../strings_in_struct_standard_input.json | 97 +++ .../for_loop_break.sol | 13 + .../for_loop_break_standard_input.json | 37 + .../for_loop_continue.sol | 13 + .../for_loop_continue_standard_input.json | 34 + .../for_loop_nested.sol | 20 + .../for_loop_nested_standard_input.json | 40 + ...signment_to_const_var_involving_keccak.sol | 9 + ...t_var_involving_keccak_standard_input.json | 73 ++ .../builtinFunctions_blobhash/blobhash.sol | 18 + .../blobhash_standard_input.json | 88 +++ .../blobhash_shadow_resolution.sol | 12 + ...hash_shadow_resolution_standard_input.json | 79 ++ .../builtinFunctions_blockhash/blockhash.sol | 15 + .../blockhash_standard_input.json | 94 +++ .../blockhash_shadow_resolution.sol | 6 + ...hash_shadow_resolution_standard_input.json | 70 ++ .../function_types_sig.sol | 26 + .../function_types_sig_standard_input.json | 91 +++ .../iterated_keccak256_with_bytes.sol | 12 + ...d_keccak256_with_bytes_standard_input.json | 46 ++ .../builtinFunctions_keccak256/keccak256.sol | 9 + .../keccak256_standard_input.json | 55 ++ .../keccak256_empty.sol | 7 + .../keccak256_empty_standard_input.json | 34 + .../keccak256_multiple_arguments.sol | 7 + ...256_multiple_arguments_standard_input.json | 49 ++ ...ltiple_arguments_with_numeric_literals.sol | 7 + ..._with_numeric_literals_standard_input.json | 85 ++ ...ultiple_arguments_with_string_literals.sol | 12 + ...s_with_string_literals_standard_input.json | 76 ++ .../keccak256_packed.sol | 12 + .../keccak256_packed_standard_input.json | 97 +++ .../keccak256_packed_complex_types.sol | 14 + ...6_packed_complex_types_standard_input.json | 43 ++ .../keccak256_with_bytes.sol | 12 + .../keccak256_with_bytes_standard_input.json | 67 ++ .../builtinFunctions_msg_sig/msg_sig.sol | 7 + .../msg_sig_standard_input.json | 58 ++ .../msg_sig_after_internal_call_is_same.sol | 11 + ..._internal_call_is_same_standard_input.json | 100 +++ .../builtinFunctions_ripemd160/ripemd160.sol | 9 + .../ripemd160_standard_input.json | 40 + .../ripemd160_empty.sol | 7 + .../ripemd160_empty_standard_input.json | 52 ++ .../ripemd160_packed.sol | 12 + .../ripemd160_packed_standard_input.json | 37 + .../builtinFunctions_sha256/sha256.sol | 9 + .../sha256_standard_input.json | 61 ++ .../sha256_empty.sol | 7 + .../sha256_empty_standard_input.json | 82 ++ .../sha256_packed.sol | 12 + .../sha256_packed_standard_input.json | 64 ++ .../byte_array_to_storage_cleanup.sol | 40 + ...ray_to_storage_cleanup_standard_input.json | 79 ++ .../c99_scoping_activation.sol | 41 + ...c99_scoping_activation_standard_input.json | 85 ++ .../calldata_array_access.sol | 18 + .../calldata_array_access_standard_input.json | 100 +++ .../calldata_array_dynamic_bytes.sol | 75 ++ ...ta_array_dynamic_bytes_standard_input.json | 55 ++ .../calldata_array_index_range_access.sol | 43 ++ ...ray_index_range_access_standard_input.json | 37 + .../calldata_array_length.sol | 32 + .../calldata_array_length_standard_input.json | 40 + .../calldata_array_three_dimensional.sol | 18 + ...rray_three_dimensional_standard_input.json | 58 ++ .../calldata_attached_to_bytes.sol | 17 + ...data_attached_to_bytes_standard_input.json | 94 +++ ...ata_attached_to_dynamic_array_or_slice.sol | 22 + ...dynamic_array_or_slice_standard_input.json | 70 ++ .../calldata_attached_to_static_array.sol | 17 + ...tached_to_static_array_standard_input.json | 82 ++ .../calldata_attached_to_struct.sol | 22 + ...ata_attached_to_struct_standard_input.json | 43 ++ .../calldata_bytes_array_bounds.sol | 10 + ...ata_bytes_array_bounds_standard_input.json | 49 ++ .../calldata_bytes_external.sol | 12 + ...alldata_bytes_external_standard_input.json | 85 ++ .../calldata_bytes_internal.sol | 10 + ...alldata_bytes_internal_standard_input.json | 91 +++ .../calldata_bytes_to_memory.sol | 7 + ...lldata_bytes_to_memory_standard_input.json | 52 ++ .../calldata_bytes_to_memory_encode.sol | 7 + ...bytes_to_memory_encode_standard_input.json | 46 ++ .../calldata_internal_function_pointer.sol | 17 + ...ernal_function_pointer_standard_input.json | 64 ++ .../calldata_internal_library.sol | 20 + ...ldata_internal_library_standard_input.json | 97 +++ .../calldata_internal_multi_array.sol | 21 + ...a_internal_multi_array_standard_input.json | 79 ++ .../calldata_internal_multi_fixed_array.sol | 17 + ...rnal_multi_fixed_array_standard_input.json | 67 ++ .../calldata_memory_mixed.sol | 19 + .../calldata_memory_mixed_standard_input.json | 88 +++ .../calldata_string_array.sol | 15 + .../calldata_string_array_standard_input.json | 73 ++ .../calldata_struct.sol | 20 + .../calldata_struct_standard_input.json | 34 + .../calldata_struct_cleaning.sol | 22 + ...lldata_struct_cleaning_standard_input.json | 61 ++ .../calldata_struct_internal.sol | 17 + ...lldata_struct_internal_standard_input.json | 76 ++ .../copy_from_calldata_removes_bytes_data.sol | 17 + ...ata_removes_bytes_data_standard_input.json | 103 +++ .../bool_conversion_v1.sol | 25 + .../bool_conversion_v1_standard_input.json | 43 ++ .../bool_conversion_v2.sol | 24 + .../bool_conversion_v2_standard_input.json | 40 + .../cleanup_address_types_shortening.sol | 30 + ...dress_types_shortening_standard_input.json | 79 ++ .../cleanup_address_types_v1.sol | 19 + ...eanup_address_types_v1_standard_input.json | 52 ++ .../cleanup_address_types_v2.sol | 18 + ...eanup_address_types_v2_standard_input.json | 61 ++ ...anup_bytes_types_shortening_OldCodeGen.sol | 16 + ..._shortening_OldCodeGen_standard_input.json | 76 ++ ...anup_bytes_types_shortening_newCodeGen.sol | 13 + ..._shortening_newCodeGen_standard_input.json | 70 ++ .../cleanup_bytes_types_v1.sol | 15 + ...cleanup_bytes_types_v1_standard_input.json | 34 + .../cleanup_bytes_types_v2.sol | 14 + ...cleanup_bytes_types_v2_standard_input.json | 37 + .../cleanup_in_compound_assign.sol | 12 + ...nup_in_compound_assign_standard_input.json | 49 ++ .../cleanup_exp_cleanup/exp_cleanup.sol | 10 + .../exp_cleanup_standard_input.json | 46 ++ .../exp_cleanup_direct.sol | 9 + .../exp_cleanup_direct_standard_input.json | 55 ++ .../exp_cleanup_nonzero_base.sol | 10 + ...p_cleanup_nonzero_base_standard_input.json | 67 ++ .../exp_cleanup_smaller_base.sol | 13 + ...p_cleanup_smaller_base_standard_input.json | 64 ++ ...xed_log_topic_during_explicit_downcast.sol | 23 + ...ring_explicit_downcast_standard_input.json | 73 ++ ...ing_explicit_downcast_during_emissions.sol | 17 + ...ncast_during_emissions_standard_input.json | 58 ++ .../negative_fractional_mod.sol | 9 + ...egative_fractional_mod_standard_input.json | 37 + .../constantEvaluator_rounding/rounding.sol | 13 + .../rounding_standard_input.json | 34 + .../asm_address_constant_regression.sol | 11 + ...ss_constant_regression_standard_input.json | 34 + .../asm_constant_file_level.sol | 9 + ...sm_constant_file_level_standard_input.json | 37 + .../constant_string.sol | 21 + .../constant_string_standard_input.json | 46 ++ .../constant_string_at_file_level.sol | 30 + ...t_string_at_file_level_standard_input.json | 40 + .../constant_variables.sol | 8 + .../constant_variables_standard_input.json | 43 ++ .../constants_at_file_level_referencing.sol | 38 + ...file_level_referencing_standard_input.json | 49 ++ .../consteval_array_length.sol | 14 + ...consteval_array_length_standard_input.json | 58 ++ .../function_unreferenced.sol | 9 + .../function_unreferenced_standard_input.json | 61 ++ .../same_constants_different_files.sol | 23 + ...stants_different_files_standard_input.json | 52 ++ .../simple_constant_variables_test.sol | 9 + ...onstant_variables_test_standard_input.json | 55 ++ .../arrays_in_constructors.sol | 32 + ...arrays_in_constructors_standard_input.json | 34 + .../base_constructor_arguments.sol | 23 + ..._constructor_arguments_standard_input.json | 76 ++ .../bytes_in_constructors_packer.sol | 32 + ...in_constructors_packer_standard_input.json | 82 ++ .../bytes_in_constructors_unpacker.sol | 18 + ..._constructors_unpacker_standard_input.json | 85 ++ .../callvalue_check.sol | 40 + .../callvalue_check_standard_input.json | 91 +++ .../constructor_arguments_external.sol | 27 + ...tor_arguments_external_standard_input.json | 70 ++ .../constructor_arguments_internal.sol | 37 + ...tor_arguments_internal_standard_input.json | 40 + .../constructor_function_argument.sol | 7 + ...ctor_function_argument_standard_input.json | 97 +++ .../constructor_function_complex.sol | 21 + ...uctor_function_complex_standard_input.json | 58 ++ .../constructor_static_array_argument.sol | 21 + ..._static_array_argument_standard_input.json | 49 ++ ...vm_exceptions_in_constructor_call_fail.sol | 18 + ..._constructor_call_fail_standard_input.json | 64 ++ ...unction_usage_in_constructor_arguments.sol | 23 + ..._constructor_arguments_standard_input.json | 100 +++ .../functions_called_by_constructor.sol | 18 + ..._called_by_constructor_standard_input.json | 94 +++ ...called_by_constructor_through_dispatch.sol | 28 + ...uctor_through_dispatch_standard_input.json | 61 ++ .../constructor_inheritance_init_order.sol | 19 + ...inheritance_init_order_standard_input.json | 52 ++ .../constructor_inheritance_init_order_2.sol | 18 + ...heritance_init_order_2_standard_input.json | 34 + ...ructor_inheritance_init_order_3_legacy.sol | 12 + ...ce_init_order_3_legacy_standard_input.json | 49 ++ ...tructor_inheritance_init_order_3_viaIR.sol | 12 + ...nce_init_order_3_viaIR_standard_input.json | 73 ++ ...r_init_inheritence_without_constructor.sol | 19 + ...ce_without_constructor_standard_input.json | 73 ++ .../no_callvalue_check.sol | 25 + .../no_callvalue_check_standard_input.json | 52 ++ .../order_of_evaluation.sol | 22 + .../order_of_evaluation_standard_input.json | 43 ++ .../payable_constructor.sol | 5 + .../payable_constructor_standard_input.json | 46 ++ .../store_function_in_constructor.sol | 20 + ...unction_in_constructor_standard_input.json | 67 ++ .../store_function_in_constructor_packed.sol | 22 + ..._in_constructor_packed_standard_input.json | 88 +++ ...nternal_unused_function_in_constructor.sol | 17 + ...unction_in_constructor_standard_input.json | 55 ++ ...unused_library_function_in_constructor.sol | 20 + ...unction_in_constructor_standard_input.json | 79 ++ ...ransient_state_variable_initialization.sol | 18 + ...ariable_initialization_standard_input.json | 37 + .../constructor_with_params.sol | 17 + ...onstructor_with_params_standard_input.json | 76 ++ ...ructor_with_params_diamond_inheritance.sol | 32 + ...ms_diamond_inheritance_standard_input.json | 100 +++ .../constructor_with_params_inheritance.sol | 22 + ...ith_params_inheritance_standard_input.json | 46 ++ .../constructor_with_params_inheritance_2.sol | 13 + ...h_params_inheritance_2_standard_input.json | 37 + .../function_type_array_to_storage.sol | 42 + ..._type_array_to_storage_standard_input.json | 34 + .../string_to_bytes.sol | 7 + .../string_to_bytes_standard_input.json | 37 + .../bound_function.sol | 40 + .../bound_function_standard_input.json | 43 ++ .../library_function.sol | 34 + .../library_function_standard_input.json | 52 ++ .../library_function_deployed.sol | 31 + ...rary_function_deployed_standard_input.json | 34 + .../module_function.sol | 36 + .../module_function_standard_input.json | 64 ++ .../module_function_deployed.sol | 32 + ...dule_function_deployed_standard_input.json | 61 ++ .../static_base_function.sol | 35 + .../static_base_function_standard_input.json | 49 ++ .../static_base_function_deployed.sol | 31 + ...base_function_deployed_standard_input.json | 37 + .../subassembly_deduplication.sol | 41 + ...assembly_deduplication_standard_input.json | 55 ++ .../super_function.sol | 35 + .../super_function_standard_input.json | 46 ++ .../super_function_deployed.sol | 31 + ...uper_function_deployed_standard_input.json | 67 ++ .../virtual_function.sol | 39 + .../virtual_function_standard_input.json | 40 + .../virtual_function_deployed.sol | 35 + ...tual_function_deployed_standard_input.json | 58 ++ .../dirty_calldata_bytes.sol | 12 + .../dirty_calldata_bytes_standard_input.json | 91 +++ .../dirty_calldata_dynamic_array.sol | 12 + ...calldata_dynamic_array_standard_input.json | 82 ++ .../ecrecover_ecrecover/ecrecover.sol | 12 + .../ecrecover_standard_input.json | 46 ++ .../ecrecover_abiV2.sol | 13 + .../ecrecover_abiV2_standard_input.json | 34 + .../failing_ecrecover_invalid_input.sol | 10 + ...crecover_invalid_input_standard_input.json | 40 + .../failing_ecrecover_invalid_input_asm.sol | 15 + ...over_invalid_input_asm_standard_input.json | 37 + ...failing_ecrecover_invalid_input_proper.sol | 20 + ...r_invalid_input_proper_standard_input.json | 43 ++ .../emit_three_identical_events.sol | 14 + ...three_identical_events_standard_input.json | 58 ++ .../emit_two_identical_events.sol | 12 + ...t_two_identical_events_standard_input.json | 40 + .../empty_contract_1/empty_contract.sol | 6 + .../empty_contract_standard_input.json | 88 +++ .../empty_for_loop_1/empty_for_loop.sol | 11 + .../empty_for_loop_standard_input.json | 55 ++ .../constructing_enums_from_ints.sol | 9 + ...ucting_enums_from_ints_standard_input.json | 37 + .../enum_explicit_overflow.sol | 31 + ...enum_explicit_overflow_standard_input.json | 40 + .../enum_explicit_overflow_homestead.sol | 30 + ...cit_overflow_homestead_standard_input.json | 34 + .../enum_referencing.sol | 38 + .../enum_referencing_standard_input.json | 46 ++ .../enum_with_256_members.sol | 58 ++ .../enum_with_256_members_standard_input.json | 49 ++ .../invalid_enum_logged.sol | 22 + .../invalid_enum_logged_standard_input.json | 43 ++ .../semanticTests/enums_minmax/minmax.sol | 9 + .../enums_minmax/minmax_standard_input.json | 64 ++ ...ract_enums_with_explicit_contract_name.sol | 9 + ...explicit_contract_name_standard_input.json | 52 ++ .../enums_using_enums/using_enums.sol | 15 + .../using_enums_standard_input.json | 58 ++ .../using_inherited_enum.sol | 12 + .../using_inherited_enum_standard_input.json | 61 ++ .../using_inherited_enum_excplicitly.sol | 12 + ...rited_enum_excplicitly_standard_input.json | 55 ++ .../error_in_library_and_interface.sol | 22 + ..._library_and_interface_standard_input.json | 49 ++ .../errors_error_selector/error_selector.sol | 48 ++ .../error_selector_standard_input.json | 85 ++ ..._calldata_uint_array_and_dynamic_array.sol | 10 + ...rray_and_dynamic_array_standard_input.json | 52 ++ .../errors_by_parameter_type.sol | 45 ++ ...rors_by_parameter_type_standard_input.json | 76 ++ .../named_error_args.sol | 8 + .../named_error_args_standard_input.json | 112 +++ .../named_parameters_shadowing_types.sol | 23 + ...meters_shadowing_types_standard_input.json | 55 ++ .../panic_via_import.sol | 16 + .../panic_via_import_standard_input.json | 91 +++ ...quire_different_errors_same_parameters.sol | 19 + ...errors_same_parameters_standard_input.json | 64 ++ ...re_error_condition_evaluated_only_once.sol | 24 + ...on_evaluated_only_once_standard_input.json | 46 ++ .../require_error_evaluation_order_1.sol | 26 + ...ror_evaluation_order_1_standard_input.json | 103 +++ .../require_error_evaluation_order_2.sol | 16 + ...ror_evaluation_order_2_standard_input.json | 97 +++ .../require_error_evaluation_order_3.sol | 15 + ...ror_evaluation_order_3_standard_input.json | 94 +++ ...quire_error_function_join_control_flow.sol | 18 + ...tion_join_control_flow_standard_input.json | 106 +++ ...quire_error_function_pointer_parameter.sol | 18 + ...tion_pointer_parameter_standard_input.json | 40 + .../require_error_multiple_arguments.sol | 18 + ...ror_multiple_arguments_standard_input.json | 37 + .../require_error_stack_check.sol | 19 + ...uire_error_stack_check_standard_input.json | 79 ++ .../require_error_string_literal.sol | 18 + ...e_error_string_literal_standard_input.json | 34 + .../require_error_string_memory.sol | 20 + ...re_error_string_memory_standard_input.json | 58 ++ .../require_error_uint256.sol | 18 + .../require_error_uint256_standard_input.json | 43 ++ .../require_inherited_error.sol | 15 + ...equire_inherited_error_standard_input.json | 61 ++ .../revert_conversion.sol | 10 + .../revert_conversion_standard_input.json | 73 ++ .../semanticTests/errors_simple/simple.sol | 8 + .../errors_simple/simple_standard_input.json | 88 +++ .../small_error_optimization.sol | 22 + ...all_error_optimization_standard_input.json | 82 ++ .../errors_using_structs/using_structs.sol | 18 + .../using_structs_standard_input.json | 67 ++ .../via_contract_type.sol | 16 + .../via_contract_type_standard_input.json | 70 ++ .../errors_via_import/via_import.sol | 23 + .../via_import_standard_input.json | 109 +++ .../errors_weird_name/weird_name.sol | 8 + .../weird_name_standard_input.json | 100 +++ .../test/semanticTests/events_event/event.sol | 21 + .../events_event/event_standard_input.json | 55 ++ .../event_access_through_base_name_emit.sol | 12 + ...through_base_name_emit_standard_input.json | 40 + .../event_anonymous.sol | 9 + .../event_anonymous_standard_input.json | 139 ++++ ...ent_anonymous_with_signature_collision.sol | 9 + ...th_signature_collision_standard_input.json | 151 ++++ ...nt_anonymous_with_signature_collision2.sol | 10 + ...h_signature_collision2_standard_input.json | 112 +++ .../event_anonymous_with_topics.sol | 9 + ..._anonymous_with_topics_standard_input.json | 103 +++ .../event_constructor.sol | 9 + .../event_constructor_standard_input.json | 130 ++++ .../event_dynamic_array_memory.sol | 13 + ...t_dynamic_array_memory_standard_input.json | 58 ++ .../event_dynamic_array_memory_v2.sol | 14 + ...ynamic_array_memory_v2_standard_input.json | 73 ++ .../event_dynamic_array_storage.sol | 18 + ..._dynamic_array_storage_standard_input.json | 133 ++++ .../event_dynamic_array_storage_v2.sol | 19 + ...namic_array_storage_v2_standard_input.json | 85 ++ .../event_dynamic_nested_array_memory_v2.sol | 17 + ...nested_array_memory_v2_standard_input.json | 64 ++ .../event_dynamic_nested_array_storage_v2.sol | 20 + ...ested_array_storage_v2_standard_input.json | 49 ++ .../events_event_emit/event_emit.sol | 9 + .../event_emit_standard_input.json | 154 ++++ .../event_emit_file_level.sol | 10 + .../event_emit_file_level_standard_input.json | 94 +++ .../event_emit_from_a_foreign_contract.sol | 13 + ...rom_a_foreign_contract_standard_input.json | 97 +++ ...emit_from_a_foreign_contract_same_name.sol | 17 + ...ign_contract_same_name_standard_input.json | 142 ++++ .../event_emit_from_other_contract.sol | 25 + ...it_from_other_contract_standard_input.json | 61 ++ ...event_emit_interface_event_via_library.sol | 19 + ...face_event_via_library_standard_input.json | 136 ++++ .../event_emit_via_interface.sol | 13 + ...ent_emit_via_interface_standard_input.json | 37 + .../event_indexed_function.sol | 9 + ...event_indexed_function_standard_input.json | 67 ++ .../event_indexed_function2.sol | 15 + ...vent_indexed_function2_standard_input.json | 43 ++ .../event_indexed_mixed.sol | 16 + .../event_indexed_mixed_standard_input.json | 52 ++ .../event_indexed_string.sol | 22 + .../event_indexed_string_standard_input.json | 145 ++++ .../event_lots_of_data.sol | 9 + .../event_lots_of_data_standard_input.json | 91 +++ .../event_no_arguments.sol | 9 + .../event_no_arguments_standard_input.json | 148 ++++ .../event_really_lots_of_data.sol | 9 + ...nt_really_lots_of_data_standard_input.json | 100 +++ ...event_really_lots_of_data_from_storage.sol | 13 + ...s_of_data_from_storage_standard_input.json | 106 +++ ...eally_really_lots_of_data_from_storage.sol | 15 + ...s_of_data_from_storage_standard_input.json | 124 +++ .../events_event_selector/event_selector.sol | 58 ++ .../event_selector_standard_input.json | 76 ++ .../event_selector_file_level.sol | 15 + ...nt_selector_file_level_standard_input.json | 34 + .../event_shadowing_file_level.sol | 38 + ...t_shadowing_file_level_standard_input.json | 115 +++ .../event_signature_in_library.sol | 21 + ...t_signature_in_library_standard_input.json | 82 ++ ..._calldata_uint_array_and_dynamic_array.sol | 11 + ...rray_and_dynamic_array_standard_input.json | 121 +++ .../events_event_string/event_string.sol | 9 + .../event_string_standard_input.json | 118 +++ .../event_struct_memory_v2.sol | 11 + ...event_struct_memory_v2_standard_input.json | 46 ++ .../event_struct_storage_v2.sol | 13 + ...vent_struct_storage_v2_standard_input.json | 70 ++ .../events_with_same_name.sol | 31 + .../events_with_same_name_standard_input.json | 79 ++ .../events_with_same_name_file_level.sol | 32 + ...h_same_name_file_level_standard_input.json | 88 +++ .../events_with_same_name_inherited_emit.sol | 30 + ...me_name_inherited_emit_standard_input.json | 109 +++ .../semanticTests/events_simple/simple.sol | 17 + .../events_simple/simple_standard_input.json | 127 +++ .../semanticTests/experimental_stub/stub.sol | 97 +++ .../stub_standard_input.json | 37 + .../experimental_type_class/type_class.sol | 67 ++ .../type_class_standard_input.json | 34 + .../literal_base.sol | 18 + .../literal_base_standard_input.json | 34 + .../signed_base.sol | 14 + .../signed_base_standard_input.json | 40 + .../exponentiation_small_exp/small_exp.sol | 14 + .../small_exp_standard_input.json | 37 + .../bit_operators.sol | 17 + .../bit_operators_standard_input.json | 46 ++ .../bytes_comparison.sol | 10 + .../bytes_comparison_standard_input.json | 49 ++ ...conditional_expression_different_types.sol | 10 + ...ession_different_types_standard_input.json | 76 ++ .../conditional_expression_false_literal.sol | 7 + ...pression_false_literal_standard_input.json | 85 ++ .../conditional_expression_functions.sol | 12 + ...l_expression_functions_standard_input.json | 37 + .../conditional_expression_multiple.sol | 13 + ...al_expression_multiple_standard_input.json | 61 ++ ...onditional_expression_storage_memory_1.sol | 27 + ...ssion_storage_memory_1_standard_input.json | 73 ++ ...onditional_expression_storage_memory_2.sol | 28 + ...ssion_storage_memory_2_standard_input.json | 64 ++ .../conditional_expression_true_literal.sol | 7 + ...xpression_true_literal_standard_input.json | 34 + .../conditional_expression_tuples.sol | 8 + ...onal_expression_tuples_standard_input.json | 55 ++ ...ditional_expression_with_return_values.sol | 8 + ...ion_with_return_values_standard_input.json | 82 ++ .../exp_operator_const.sol | 5 + .../exp_operator_const_standard_input.json | 52 ++ .../exp_operator_const_signed.sol | 5 + ..._operator_const_signed_standard_input.json | 88 +++ .../exp_zero_literal.sol | 5 + .../exp_zero_literal_standard_input.json | 67 ++ .../inc_dec_operators.sol | 15 + .../inc_dec_operators_standard_input.json | 40 + .../module_from_ternary_expression.sol | 15 + ...rom_ternary_expression_standard_input.json | 43 ++ .../tuple_from_ternary_expression.sol | 9 + ...rom_ternary_expression_standard_input.json | 79 ++ .../unary_too_long_literal.sol | 9 + ...unary_too_long_literal_standard_input.json | 70 ++ .../uncalled_address_transfer_send.sol | 10 + ..._address_transfer_send_standard_input.json | 58 ++ .../FixedFeeRegistrar.sol | 121 +++ .../FixedFeeRegistrar_standard_input.json | 37 + .../base64_inline_asm.sol | 96 +++ .../base64_inline_asm_standard_input.json | 37 + .../base64_no_inline_asm.sol | 39 + .../base64_no_inline_asm_standard_input.json | 34 + .../PRBMathCommon.sol | 361 +++++++++ .../PRBMathCommon_standard_input.json | 40 + .../PRBMathSD59x18.sol | 578 ++++++++++++++ .../PRBMathSD59x18_standard_input.json | 34 + .../PRBMathUD60x18.sol | 437 +++++++++++ .../PRBMathUD60x18_standard_input.json | 37 + .../stringutils.sol | 725 ++++++++++++++++++ .../stringutils_standard_input.json | 34 + .../externalContracts_base64/base64.sol | 63 ++ .../base64_standard_input.json | 55 ++ .../deposit_contract.sol | 213 +++++ .../deposit_contract_standard_input.json | 40 + .../prbmath_signed.sol | 96 +++ .../prbmath_signed_standard_input.json | 46 ++ .../prbmath_unsigned.sol | 96 +++ .../prbmath_unsigned_standard_input.json | 49 ++ .../ramanujan_pi.sol | 45 ++ .../ramanujan_pi_standard_input.json | 34 + .../externalContracts_snark/snark.sol | 304 ++++++++ .../snark_standard_input.json | 43 ++ .../externalContracts_strings/strings.sol | 77 ++ .../strings_standard_input.json | 52 ++ .../external.sol | 2 + .../external_standard_input.json | 37 + .../import.sol | 2 + .../import_standard_input.json | 34 + .../import_with_subdir.sol | 1 + .../import_with_subdir_standard_input.json | 43 ++ .../other_external.sol | 2 + .../other_external_standard_input.json | 40 + .../import.sol | 1 + .../import_standard_input.json | 34 + .../sub_external.sol | 2 + .../sub_external_standard_input.json | 37 + .../a.sol | 2 + .../a_standard_input.json | 40 + .../c.sol | 2 + .../c_standard_input.json | 37 + .../d.sol | 2 + .../d_standard_input.json | 34 + .../d.sol | 2 + .../d_standard_input.json | 34 + .../externalSource__relative_imports_c/c.sol | 2 + .../c_standard_input.json | 37 + .../b.sol | 3 + .../b_standard_input.json | 34 + .../g.sol | 3 + .../g_standard_input.json | 34 + .../a.sol | 2 + .../a_standard_input.json | 37 + .../contract.sol | 8 + .../contract_standard_input.json | 34 + .../externalSource__relative_imports_h/h.sol | 2 + .../h_standard_input.json | 34 + .../b.sol | 2 + .../b_standard_input.json | 40 + .../a.sol | 2 + .../a_standard_input.json | 37 + .../contract.sol | 2 + .../contract_standard_input.json | 34 + .../dot_a.sol | 2 + .../dot_a_standard_input.json | 34 + .../dot_dot_b.sol | 2 + .../dot_dot_b_standard_input.json | 37 + .../multiple_equals_signs.sol | 6 + .../multiple_equals_signs_standard_input.json | 34 + .../multiple_external_source.sol | 8 + ...ltiple_external_source_standard_input.json | 46 ++ .../multisource.sol | 12 + .../multisource_standard_input.json | 55 ++ .../non_normalized_paths.sol | 10 + .../non_normalized_paths_standard_input.json | 52 ++ .../relative_imports.sol | 12 + .../relative_imports_standard_input.json | 40 + .../externalSource_source/source.sol | 6 + .../source_standard_input.json | 58 ++ .../source_import.sol | 8 + .../source_import_standard_input.json | 37 + .../source_import_subdir.sol | 8 + .../source_import_subdir_standard_input.json | 49 ++ .../source_name_starting_with_dots.sol | 10 + ...ame_starting_with_dots_standard_input.json | 61 ++ .../source_remapping.sol | 10 + .../source_remapping_standard_input.json | 43 ++ .../call_forward_bytes.sol | 25 + .../call_forward_bytes_standard_input.json | 58 ++ .../falback_return.sol | 16 + .../falback_return_standard_input.json | 46 ++ .../fallback_argument.sol | 16 + .../fallback_argument_standard_input.json | 34 + .../fallback_argument_to_storage.sol | 16 + ...ck_argument_to_storage_standard_input.json | 52 ++ .../fallback_or_receive.sol | 17 + .../fallback_or_receive_standard_input.json | 43 ++ .../fallback_override.sol | 18 + .../fallback_override_standard_input.json | 37 + .../fallback_override2.sol | 17 + .../fallback_override2_standard_input.json | 49 ++ .../fallback_override_multi.sol | 21 + ...allback_override_multi_standard_input.json | 55 ++ .../fallback_return_data.sol | 13 + .../fallback_return_data_standard_input.json | 40 + .../fallback_inherited/inherited.sol | 10 + .../inherited_standard_input.json | 61 ++ .../short_data_calls_fallback.sol | 17 + ...rt_data_calls_fallback_standard_input.json | 64 ++ .../semanticTests/freeFunctions_easy/easy.sol | 11 + .../easy_standard_input.json | 46 ++ .../free_namesake_contract_function.sol | 8 + ...sake_contract_function_standard_input.json | 52 ++ .../free_runtimecode.sol | 15 + .../free_runtimecode_standard_input.json | 37 + .../freeFunctions_import/import.sol | 18 + .../import_standard_input.json | 34 + .../libraries_from_free.sol | 21 + .../libraries_from_free_standard_input.json | 43 ++ .../new_operator.sol | 17 + .../new_operator_standard_input.json | 49 ++ .../freeFunctions_overloads/overloads.sol | 14 + .../overloads_standard_input.json | 40 + .../freeFunctions_recursion/recursion.sol | 21 + .../recursion_standard_input.json | 55 ++ .../storage_calldata_refs.sol | 15 + .../storage_calldata_refs_standard_input.json | 58 ++ .../array_multiple_local_vars.sol | 28 + ...ay_multiple_local_vars_standard_input.json | 139 ++++ .../bare_call_no_returndatacopy.sol | 8 + ...call_no_returndatacopy_standard_input.json | 160 ++++ ..._attached_library_function_on_function.sol | 13 + ...y_function_on_function_standard_input.json | 46 ++ ...d_library_function_on_storage_variable.sol | 13 + ...on_on_storage_variable_standard_input.json | 109 +++ ...ll_attached_library_function_on_string.sol | 17 + ...ary_function_on_string_standard_input.json | 148 ++++ .../call_function_returning_function.sol | 25 + ...ion_returning_function_standard_input.json | 82 ++ ...function_returning_nothing_via_pointer.sol | 16 + ...ng_nothing_via_pointer_standard_input.json | 55 ++ .../call_internal_function_via_expression.sol | 22 + ...unction_via_expression_standard_input.json | 163 ++++ ...n_with_multislot_arguments_via_pointer.sol | 29 + ..._arguments_via_pointer_standard_input.json | 169 ++++ .../call_options_overload.sol | 16 + .../call_options_overload_standard_input.json | 112 +++ .../calling_nonexisting_contract_throws.sol | 27 + ...isting_contract_throws_standard_input.json | 145 ++++ .../calling_other_functions.sol | 20 + ...alling_other_functions_standard_input.json | 178 +++++ .../calling_uninitialized_function.sol | 16 + ...uninitialized_function_standard_input.json | 97 +++ ...lling_uninitialized_function_in_detail.sol | 19 + ...zed_function_in_detail_standard_input.json | 133 ++++ ...g_uninitialized_function_through_array.sol | 19 + ...function_through_array_standard_input.json | 175 +++++ .../conditional_with_arguments.sol | 10 + ...itional_with_arguments_standard_input.json | 70 ++ .../creation_function_call_no_args.sol | 15 + ..._function_call_no_args_standard_input.json | 106 +++ .../creation_function_call_with_args.sol | 24 + ...unction_call_with_args_standard_input.json | 52 ++ .../creation_function_call_with_salt.sol | 26 + ...unction_call_with_salt_standard_input.json | 151 ++++ .../delegatecall_return_value.sol | 37 + ...egatecall_return_value_standard_input.json | 85 ++ ...elegatecall_return_value_pre_byzantium.sol | 39 + ...rn_value_pre_byzantium_standard_input.json | 121 +++ .../disordered_named_args.sol | 6 + .../disordered_named_args_standard_input.json | 130 ++++ .../external_call.sol | 14 + .../external_call_standard_input.json | 91 +++ .../external_call_at_construction_time.sol | 24 + ...l_at_construction_time_standard_input.json | 127 +++ .../external_call_dynamic_returndata.sol | 22 + ...all_dynamic_returndata_standard_input.json | 34 + .../external_call_to_nonexisting.sol | 37 + ...al_call_to_nonexisting_standard_input.json | 58 ++ ...ernal_call_to_nonexisting_debugstrings.sol | 40 + ...nexisting_debugstrings_standard_input.json | 37 + .../external_call_value.sol | 14 + .../external_call_value_standard_input.json | 166 ++++ .../external_function.sol | 15 + .../external_function_standard_input.json | 103 +++ .../external_public_override.sol | 19 + ...ternal_public_override_standard_input.json | 88 +++ .../failed_create.sol | 36 + .../failed_create_standard_input.json | 136 ++++ .../file_level_call_via_module.sol | 13 + ..._level_call_via_module_standard_input.json | 67 ++ .../gas_and_value_basic.sol | 49 ++ .../gas_and_value_basic_standard_input.json | 157 ++++ .../gas_and_value_brace_syntax.sol | 48 ++ ...and_value_brace_syntax_standard_input.json | 172 +++++ .../base_base_overload.sol | 50 ++ .../base_base_overload_standard_input.json | 58 ++ .../base_overload.sol | 29 + .../base_overload_standard_input.json | 43 ++ .../call_base.sol | 13 + .../call_base_standard_input.json | 40 + .../call_base_base.sol | 27 + .../call_base_base_standard_input.json | 34 + .../call_base_base_explicit.sol | 30 + ...all_base_base_explicit_standard_input.json | 49 ++ .../call_base_explicit.sol | 13 + .../call_base_explicit_standard_input.json | 52 ++ .../call_unimplemented_base.sol | 18 + ...all_unimplemented_base_standard_input.json | 55 ++ ...kip_unimplemented_in_abstract_contract.sol | 19 + ...d_in_abstract_contract_standard_input.json | 37 + .../super_skip_unimplemented_in_interface.sol | 19 + ...plemented_in_interface_standard_input.json | 46 ++ .../mapping_array_internal_argument.sol | 26 + ...rray_internal_argument_standard_input.json | 115 +++ .../mapping_internal_argument.sol | 21 + ...ping_internal_argument_standard_input.json | 124 +++ .../mapping_internal_return.sol | 22 + ...apping_internal_return_standard_input.json | 61 ++ .../member_accessors.sol | 22 + .../member_accessors_standard_input.json | 142 ++++ .../multiple_functions.sol | 14 + .../multiple_functions_standard_input.json | 154 ++++ .../multiple_return_values.sol | 7 + ...multiple_return_values_standard_input.json | 43 ++ .../functionCall_named_args/named_args.sol | 8 + .../named_args_standard_input.json | 64 ++ .../named_args_overload.sol | 35 + .../named_args_overload_standard_input.json | 118 +++ .../precompile_extcodesize_check.sol | 33 + ...pile_extcodesize_check_standard_input.json | 76 ++ .../return_size_bigger_than_expected.sol | 31 + ...e_bigger_than_expected_standard_input.json | 79 ++ .../return_size_shorter_than_expected.sol | 32 + ..._shorter_than_expected_standard_input.json | 40 + ...n_expected_evm_version_after_homestead.sol | 34 + ...ersion_after_homestead_standard_input.json | 100 +++ .../send_zero_ether.sol | 22 + .../send_zero_ether_standard_input.json | 49 ++ .../transaction_status.sol | 9 + .../transaction_status_standard_input.json | 94 +++ .../functionCall_value_test/value_test.sol | 8 + .../value_test_standard_input.json | 73 ++ .../function_selector_via_contract_name.sol | 20 + ...ctor_via_contract_name_standard_input.json | 34 + .../address_member.sol | 10 + .../address_member_standard_input.json | 76 ++ ...l_to_zero_initialized_function_type_ir.sol | 27 + ...lized_function_type_ir_standard_input.json | 106 +++ ..._zero_initialized_function_type_legacy.sol | 27 + ...d_function_type_legacy_standard_input.json | 103 +++ ...or_external_function_cleans_dirty_bits.sol | 16 + ...tion_cleans_dirty_bits_standard_input.json | 73 ++ ...rison_operators_for_external_functions.sol | 79 ++ ...for_external_functions_standard_input.json | 37 + ...on_with_same_id_in_internal_dispatcher.sol | 9 + ...in_internal_dispatcher_standard_input.json | 82 ++ ..._to_function_pointers_with_memory_type.sol | 10 + ...nters_with_memory_type_standard_input.json | 124 +++ .../function_delete_stack.sol | 13 + .../function_delete_stack_standard_input.json | 67 ++ .../function_delete_storage.sol | 26 + ...unction_delete_storage_standard_input.json | 58 ++ .../function_external_delete_storage.sol | 37 + ...xternal_delete_storage_standard_input.json | 85 ++ .../function_type_library_internal.sol | 25 + ..._type_library_internal_standard_input.json | 43 ++ .../inline_array_with_value_call_option.sol | 10 + ...with_value_call_option_standard_input.json | 49 ++ .../mapping_of_functions.sol | 33 + .../mapping_of_functions_standard_input.json | 55 ++ .../pass_function_types_externally.sol | 20 + ...ction_types_externally_standard_input.json | 112 +++ .../pass_function_types_internally.sol | 15 + ...ction_types_internally_standard_input.json | 88 +++ ...e_function_in_construction_and_runtime.sol | 18 + ...nstruction_and_runtime_standard_input.json | 115 +++ ...onstruction_and_runtime_equality_check.sol | 17 + ...runtime_equality_check_standard_input.json | 97 +++ .../functionTypes_selector_1/selector_1.sol | 14 + .../selector_1_standard_input.json | 70 ++ .../functionTypes_selector_2/selector_2.sol | 14 + .../selector_2_standard_input.json | 64 ++ .../selector_assignment_expression.sol | 10 + ..._assignment_expression_standard_input.json | 34 + .../selector_expression_side_effect.sol | 13 + ...expression_side_effect_standard_input.json | 94 +++ .../selector_ternary.sol | 10 + .../selector_ternary_standard_input.json | 61 ++ ...ry_function_pointer_from_function_call.sol | 19 + ...ter_from_function_call_standard_input.json | 118 +++ ...eck_on_adding_gas_variable_to_function.sol | 23 + ...s_variable_to_function_standard_input.json | 40 + .../store_function.sol | 32 + .../store_function_standard_input.json | 121 +++ .../struct_with_external_function.sol | 31 + ...with_external_function_standard_input.json | 109 +++ .../struct_with_functions.sol | 31 + .../struct_with_functions_standard_input.json | 46 ++ .../ternary_contract_internal_function.sol | 10 + ...ract_internal_function_standard_input.json | 79 ++ ...ary_contract_library_internal_function.sol | 13 + ...rary_internal_function_standard_input.json | 100 +++ .../ternary_contract_public_function.sol | 10 + ...ntract_public_function_standard_input.json | 91 +++ ...ialized_internal_storage_function_call.sol | 10 + ..._storage_function_call_standard_input.json | 52 ++ .../array_mapping_struct.sol | 29 + .../array_mapping_struct_standard_input.json | 34 + .../semanticTests/getters_arrays/arrays.sol | 12 + .../getters_arrays/arrays_standard_input.json | 43 ++ .../semanticTests/getters_bytes/bytes.sol | 8 + .../getters_bytes/bytes_standard_input.json | 52 ++ .../semanticTests/getters_mapping/mapping.sol | 9 + .../mapping_standard_input.json | 49 ++ .../mapping_array_struct.sol | 27 + .../mapping_array_struct_standard_input.json | 40 + .../mapping_of_string.sol | 16 + .../mapping_of_string_standard_input.json | 70 ++ .../mapping_to_struct.sol | 18 + .../mapping_to_struct_standard_input.json | 46 ++ .../mapping_with_names.sol | 9 + .../mapping_with_names_standard_input.json | 58 ++ .../string_and_bytes.sol | 16 + .../string_and_bytes_standard_input.json | 61 ++ .../struct_with_bytes.sol | 18 + .../struct_with_bytes_standard_input.json | 55 ++ .../struct_with_bytes_simple.sol | 17 + ...ruct_with_bytes_simple_standard_input.json | 64 ++ .../transient_value_types.sol | 14 + .../transient_value_types_standard_input.json | 37 + ...transient_value_types_multi_frame_call.sol | 22 + ...types_multi_frame_call_standard_input.json | 73 ++ .../getters_value_types/value_types.sol | 32 + .../value_types_standard_input.json | 67 ++ .../assign_at_declaration.sol | 8 + .../assign_at_declaration_standard_input.json | 52 ++ .../assign_from_immutables.sol | 18 + ...assign_from_immutables_standard_input.json | 46 ++ .../semanticTests/immutable_delete/delete.sol | 15 + .../delete_standard_input.json | 64 ++ .../fun_read_in_ctor.sol | 20 + .../fun_read_in_ctor_standard_input.json | 85 ++ .../semanticTests/immutable_getter/getter.sol | 5 + .../getter_standard_input.json | 55 ++ .../getter_call_in_constructor.sol | 17 + ...er_call_in_constructor_standard_input.json | 58 ++ .../immutable_signed.sol | 13 + .../immutable_signed_standard_input.json | 76 ++ .../immutable_tag_too_large_bug.sol | 48 ++ ...able_tag_too_large_bug_standard_input.json | 67 ++ .../increment_decrement.sol | 18 + .../increment_decrement_standard_input.json | 34 + .../immutable_inheritance/inheritance.sol | 30 + .../inheritance_standard_input.json | 43 ++ .../internal_function_pointer.sol | 15 + ...ernal_function_pointer_standard_input.json | 73 ++ .../multi_creation.sol | 37 + .../multi_creation_standard_input.json | 40 + .../multiple_initializations.sol | 27 + ...ltiple_initializations_standard_input.json | 70 ++ .../immutable_read_in_ctor/read_in_ctor.sol | 15 + .../read_in_ctor_standard_input.json | 49 ++ .../small_types_in_reverse.sol | 19 + ...small_types_in_reverse_standard_input.json | 37 + .../semanticTests/immutable_stub/stub.sol | 13 + .../immutable_stub/stub_standard_input.json | 79 ++ .../immutable_uninitialized/uninitialized.sol | 11 + .../uninitialized_standard_input.json | 82 ++ .../immutable_use_scratch/use_scratch.sol | 25 + .../use_scratch_standard_input.json | 61 ++ .../access_base_storage.sol | 27 + .../access_base_storage_standard_input.json | 43 ++ .../address_overload_resolution.sol | 29 + ...ss_overload_resolution_standard_input.json | 49 ++ ...base_access_to_function_type_variables.sol | 20 + ...unction_type_variables_standard_input.json | 100 +++ .../external_public_calldata.sol | 18 + ...ternal_public_calldata_standard_input.json | 34 + .../derived_overload_base_function_direct.sol | 18 + ...d_base_function_direct_standard_input.json | 46 ++ ...erived_overload_base_function_indirect.sol | 26 + ...base_function_indirect_standard_input.json | 91 +++ .../explicit_base_class.sol | 26 + .../explicit_base_class_standard_input.json | 34 + .../inherited_constant_state_var.sol | 12 + ...ted_constant_state_var_standard_input.json | 55 ++ .../inherited_function.sol | 18 + .../inherited_function_standard_input.json | 73 ++ ...d_function_calldata_calldata_interface.sol | 27 + ...ata_calldata_interface_standard_input.json | 67 ++ .../inherited_function_calldata_memory.sol | 21 + ...nction_calldata_memory_standard_input.json | 64 ++ ...ted_function_calldata_memory_interface.sol | 29 + ...ldata_memory_interface_standard_input.json | 85 ++ .../inherited_function_from_a_library.sol | 18 + ...unction_from_a_library_standard_input.json | 82 ++ .../inherited_function_through_dispatch.sol | 19 + ...ction_through_dispatch_standard_input.json | 40 + .../member_notation_ctor.sol | 26 + .../member_notation_ctor_standard_input.json | 37 + ...rloaded_function_call_resolve_to_first.sol | 15 + ..._call_resolve_to_first_standard_input.json | 58 ++ ...loaded_function_call_resolve_to_second.sol | 15 + ...call_resolve_to_second_standard_input.json | 106 +++ .../overloaded_function_call_with_if_else.sol | 17 + ...tion_call_with_if_else_standard_input.json | 79 ++ .../pass_dynamic_arguments_to_the_base.sol | 18 + ..._arguments_to_the_base_standard_input.json | 76 ++ ...ass_dynamic_arguments_to_the_base_base.sol | 23 + ...ments_to_the_base_base_standard_input.json | 88 +++ ...ic_arguments_to_the_base_base_with_gap.sol | 23 + ...the_base_base_with_gap_standard_input.json | 52 ++ .../super_in_constructor.sol | 34 + .../super_in_constructor_standard_input.json | 61 ++ .../super_in_constructor_assignment.sol | 37 + ...constructor_assignment_standard_input.json | 103 +++ .../super_overload.sol | 26 + .../super_overload_standard_input.json | 94 +++ .../transient_storage_state_variable.sol | 22 + ...storage_state_variable_standard_input.json | 109 +++ ...orage_state_variable_abstract_contract.sol | 26 + ...able_abstract_contract_standard_input.json | 70 ++ .../value_for_constructor.sol | 50 ++ .../value_for_constructor_standard_input.json | 97 +++ .../basefee_berlin_function.sol | 21 + ...asefee_berlin_function_standard_input.json | 199 +++++ .../blobbasefee_shanghai_function.sol | 21 + ...efee_shanghai_function_standard_input.json | 139 ++++ .../inlineAssembly_blobhash/blobhash.sol | 11 + .../blobhash_standard_input.json | 172 +++++ .../blobhash_index_exceeding_blob_count.sol | 14 + ...x_exceeding_blob_count_standard_input.json | 88 +++ .../blobhash_pre_cancun.sol | 21 + .../blobhash_pre_cancun_standard_input.json | 229 ++++++ .../calldata_array_assign_dynamic.sol | 8 + ...a_array_assign_dynamic_standard_input.json | 58 ++ .../calldata_array_assign_static.sol | 8 + ...ta_array_assign_static_standard_input.json | 169 ++++ .../calldata_array_read.sol | 10 + .../calldata_array_read_standard_input.json | 37 + .../calldata_assign.sol | 8 + .../calldata_assign_standard_input.json | 112 +++ .../calldata_assign_from_nowhere.sol | 7 + ...ta_assign_from_nowhere_standard_input.json | 187 +++++ .../calldata_length_read.sol | 16 + .../calldata_length_read_standard_input.json | 94 +++ .../calldata_offset_read.sol | 17 + .../calldata_offset_read_standard_input.json | 109 +++ .../calldata_offset_read_write.sol | 15 + ...data_offset_read_write_standard_input.json | 211 +++++ .../calldata_struct_assign.sol | 16 + ...calldata_struct_assign_standard_input.json | 133 ++++ .../calldata_struct_assign_and_return.sol | 21 + ...ruct_assign_and_return_standard_input.json | 43 ++ .../inlineAssembly_chainid/chainid.sol | 11 + .../chainid_standard_input.json | 154 ++++ .../constant_access.sol | 18 + .../constant_access_standard_input.json | 184 +++++ .../constant_access_referencing.sol | 26 + ...ant_access_referencing_standard_input.json | 118 +++ .../inlineAssembly_difficulty/difficulty.sol | 11 + .../difficulty_standard_input.json | 232 ++++++ .../external_function_pointer_address.sol | 17 + ...nction_pointer_address_standard_input.json | 61 ++ ...al_function_pointer_address_assignment.sol | 16 + ...ter_address_assignment_standard_input.json | 49 ++ .../external_function_pointer_selector.sol | 21 + ...ction_pointer_selector_standard_input.json | 124 +++ ...l_function_pointer_selector_assignment.sol | 16 + ...er_selector_assignment_standard_input.json | 163 ++++ .../external_identifier_access_shadowing.sol | 10 + ...ifier_access_shadowing_standard_input.json | 106 +++ .../function_name_clash.sol | 11 + .../function_name_clash_standard_input.json | 151 ++++ ...inline_assembly_embedded_function_call.sol | 24 + ...embedded_function_call_standard_input.json | 115 +++ .../inline_assembly_for.sol | 23 + .../inline_assembly_for_standard_input.json | 250 ++++++ .../inline_assembly_for2.sol | 26 + .../inline_assembly_for2_standard_input.json | 157 ++++ .../inline_assembly_function_call.sol | 18 + ...assembly_function_call_standard_input.json | 136 ++++ .../inline_assembly_function_call2.sol | 21 + ...ssembly_function_call2_standard_input.json | 196 +++++ ...line_assembly_function_call_assignment.sol | 20 + ...nction_call_assignment_standard_input.json | 46 ++ .../inline_assembly_if.sol | 14 + .../inline_assembly_if_standard_input.json | 79 ++ .../inline_assembly_in_modifiers.sol | 32 + ..._assembly_in_modifiers_standard_input.json | 127 +++ .../inline_assembly_memory_access.sol | 12 + ...assembly_memory_access_standard_input.json | 64 ++ .../inline_assembly_read_and_write_stack.sol | 10 + ...y_read_and_write_stack_standard_input.json | 226 ++++++ .../inline_assembly_recursion.sol | 25 + ...ine_assembly_recursion_standard_input.json | 130 ++++ .../inline_assembly_storage_access.sol | 21 + ...ssembly_storage_access_standard_input.json | 175 +++++ ...ssembly_storage_access_inside_function.sol | 22 + ...access_inside_function_standard_input.json | 238 ++++++ ...line_assembly_storage_access_local_var.sol | 16 + ...orage_access_local_var_standard_input.json | 223 ++++++ ...ne_assembly_storage_access_via_pointer.sol | 24 + ...age_access_via_pointer_standard_input.json | 40 + .../inline_assembly_switch.sol | 21 + ...inline_assembly_switch_standard_input.json | 148 ++++ ...ansient_storage_access_inside_function.sol | 22 + ...access_inside_function_standard_input.json | 205 +++++ .../inline_assembly_write_to_stack.sol | 10 + ...ssembly_write_to_stack_standard_input.json | 241 ++++++ .../inlineasm_empty_let.sol | 12 + .../inlineasm_empty_let_standard_input.json | 55 ++ .../keccak256_assembly.sol | 9 + .../keccak256_assembly_standard_input.json | 193 +++++ .../keccak256_optimization.sol | 14 + ...keccak256_optimization_standard_input.json | 73 ++ ...ptimizer_bug_different_memory_location.sol | 14 + ...ferent_memory_location_standard_input.json | 121 +++ .../keccak256_optimizer_cache_bug.sol | 19 + ...56_optimizer_cache_bug_standard_input.json | 67 ++ .../keccak_optimization_bug_string.sol | 13 + ...ptimization_bug_string_standard_input.json | 52 ++ .../keccak_yul_optimization.sol | 33 + ...eccak_yul_optimization_standard_input.json | 76 ++ .../inlineAssembly_leave/leave.sol | 14 + .../leave_standard_input.json | 214 ++++++ .../inlineAssembly_mcopy/mcopy.sol | 14 + .../mcopy_standard_input.json | 208 +++++ .../mcopy_as_identifier_pre_cancun.sol | 22 + ..._identifier_pre_cancun_standard_input.json | 181 +++++ .../mcopy_empty.sol | 18 + .../mcopy_empty_standard_input.json | 70 ++ .../mcopy_overlap.sol | 39 + .../mcopy_overlap_standard_input.json | 97 +++ .../optimize_memory_store_multi_block.sol | 29 + ...mory_store_multi_block_standard_input.json | 247 ++++++ ...ize_memory_store_multi_block_bugreport.sol | 23 + ..._multi_block_bugreport_standard_input.json | 202 +++++ .../inlineAssembly_prevrandao/prevrandao.sol | 11 + .../prevrandao_standard_input.json | 178 +++++ .../selfbalance.sol | 11 + .../selfbalance_standard_input.json | 34 + .../shadowing_local_function_opcode.sol | 11 + ..._local_function_opcode_standard_input.json | 91 +++ .../slot_access.sol | 33 + .../slot_access_standard_input.json | 244 ++++++ .../slot_access_via_mapping_pointer.sol | 31 + ...ss_via_mapping_pointer_standard_input.json | 220 ++++++ ...load_tstore_not_reserved_before_cancun.sol | 25 + ...reserved_before_cancun_standard_input.json | 82 ++ .../transient_storage_creation.sol | 14 + ...sient_storage_creation_standard_input.json | 103 +++ .../transient_storage_low_level_calls.sol | 76 ++ ...torage_low_level_calls_standard_input.json | 190 +++++ ..._multiple_calls_different_transactions.sol | 24 + ...different_transactions_standard_input.json | 166 ++++ ...ransient_storage_multiple_transactions.sol | 38 + ..._multiple_transactions_standard_input.json | 142 ++++ ...storage_reset_between_creation_runtime.sol | 24 + ...tween_creation_runtime_standard_input.json | 217 ++++++ .../transient_storage_sanity_checks.sol | 24 + ..._storage_sanity_checks_standard_input.json | 85 ++ .../transient_storage_selfdestruct.sol | 54 ++ ...t_storage_selfdestruct_standard_input.json | 160 ++++ ...ansient_storage_simple_reentrancy_lock.sol | 22 + ...simple_reentrancy_lock_standard_input.json | 145 ++++ .../inlineAssembly_truefalse/truefalse.sol | 10 + .../truefalse_standard_input.json | 100 +++ .../tstore_hidden_staticcall.sol | 23 + ...tore_hidden_staticcall_standard_input.json | 235 ++++++ .../semanticTests/integer_basic/basic.sol | 22 + .../integer_basic/basic_standard_input.json | 46 ++ .../test/semanticTests/integer_int/int.sol | 243 ++++++ .../integer_int/int_standard_input.json | 37 + .../many_local_variables.sol | 9 + .../many_local_variables_standard_input.json | 43 ++ .../small_signed_types.sol | 7 + .../small_signed_types_standard_input.json | 40 + .../test/semanticTests/integer_uint/uint.sol | 242 ++++++ .../integer_uint/uint_standard_input.json | 34 + .../semanticTests/interfaceID_homer/homer.sol | 35 + .../homer_standard_input.json | 43 ++ .../homer_interfaceId.sol | 35 + .../homer_interfaceId_standard_input.json | 46 ++ .../interfaceId_events.sol | 18 + .../interfaceId_events_standard_input.json | 34 + .../interfaceID_interfaces/interfaces.sol | 61 ++ .../interfaces_standard_input.json | 49 ++ .../semanticTests/interfaceID_lisa/lisa.sol | 46 ++ .../interfaceID_lisa/lisa_standard_input.json | 37 + .../lisa_interfaceId.sol | 46 ++ .../lisa_interfaceId_standard_input.json | 40 + .../interface_inheritance_conversions.sol | 43 ++ ...nheritance_conversions_standard_input.json | 97 +++ .../isoltestFormatting.sol | 13 + .../isoltestFormatting_standard_input.json | 70 ++ .../isoltestTesting_account/account.sol | 46 ++ .../account_standard_input.json | 37 + .../balance_other_contract.sol | 30 + ...balance_other_contract_standard_input.json | 43 ++ .../balance_with_balance.sol | 6 + .../balance_with_balance_standard_input.json | 34 + .../balance_with_balance2.sol | 6 + .../balance_with_balance2_standard_input.json | 49 ++ .../balance_without_balance.sol | 5 + ...alance_without_balance_standard_input.json | 40 + .../isoltestTesting_builtins/builtins.sol | 4 + .../builtins_standard_input.json | 52 ++ .../isoltestTesting_effects/effects.sol | 13 + .../effects_standard_input.json | 55 ++ .../format_raw_string_with_control_chars.sol | 10 + ...ing_with_control_chars_standard_input.json | 46 ++ .../storage_empty.sol | 4 + .../storage_empty_standard_input.json | 34 + .../storage_nonempty.sol | 8 + .../storage_nonempty_standard_input.json | 37 + ...al_library_function_accepting_calldata.sol | 17 + ...ion_accepting_calldata_standard_input.json | 49 ++ ...al_library_function_returning_calldata.sol | 17 + ...ion_returning_calldata_standard_input.json | 130 ++++ ...ibrary_function_accepting_calldata.sol.sol | 20 + ...ion_accepting_calldata_standard_input.json | 211 +++++ ...ic_library_function_returning_calldata.sol | 20 + ...ion_returning_calldata_standard_input.json | 181 +++++ ...l_call_with_function_pointer_parameter.sol | 24 + ...tion_pointer_parameter_standard_input.json | 208 +++++ ...rnal_call_with_storage_array_parameter.sol | 17 + ...torage_array_parameter_standard_input.json | 190 +++++ ...al_call_with_storage_mapping_parameter.sol | 17 + ...rage_mapping_parameter_standard_input.json | 67 ++ ...nternal_call_attached_with_parentheses.sol | 24 + ...ached_with_parentheses_standard_input.json | 124 +++ ...ernal_call_unattached_with_parentheses.sol | 13 + ...ached_with_parentheses_standard_input.json | 43 ++ .../internal_library_function.sol | 20 + ...ernal_library_function_standard_input.json | 70 ++ ...l_library_function_attached_to_address.sol | 16 + ...on_attached_to_address_standard_input.json | 127 +++ ...ttached_to_address_named_send_transfer.sol | 19 + ...ss_named_send_transfer_standard_input.json | 112 +++ ...ction_attached_to_array_named_pop_push.sol | 17 + ...o_array_named_pop_push_standard_input.json | 151 ++++ ...rnal_library_function_attached_to_bool.sol | 18 + ...ction_attached_to_bool_standard_input.json | 169 ++++ ..._library_function_attached_to_contract.sol | 18 + ...n_attached_to_contract_standard_input.json | 106 +++ ...ary_function_attached_to_dynamic_array.sol | 19 + ...ached_to_dynamic_array_standard_input.json | 199 +++++ ...rnal_library_function_attached_to_enum.sol | 19 + ...ction_attached_to_enum_standard_input.json | 163 ++++ ...ion_attached_to_external_function_type.sol | 20 + ...external_function_type_standard_input.json | 103 +++ ...brary_function_attached_to_fixed_array.sol | 19 + ...ttached_to_fixed_array_standard_input.json | 217 ++++++ ...brary_function_attached_to_fixed_bytes.sol | 15 + ...ttached_to_fixed_bytes_standard_input.json | 34 + ...l_library_function_attached_to_integer.sol | 15 + ...on_attached_to_integer_standard_input.json | 184 +++++ ...library_function_attached_to_interface.sol | 19 + ..._attached_to_interface_standard_input.json | 172 +++++ ...ion_attached_to_internal_function_type.sol | 19 + ...internal_function_type_standard_input.json | 46 ++ ..._internal_function_type_named_selector.sol | 19 + ...on_type_named_selector_standard_input.json | 145 ++++ ...l_library_function_attached_to_literal.sol | 24 + ...on_attached_to_literal_standard_input.json | 202 +++++ ...l_library_function_attached_to_mapping.sol | 20 + ...on_attached_to_mapping_standard_input.json | 109 +++ ...on_attached_to_string_accepting_memory.sol | 16 + ...tring_accepting_memory_standard_input.json | 58 ++ ...n_attached_to_string_accepting_storage.sol | 20 + ...ring_accepting_storage_standard_input.json | 118 +++ ...al_library_function_attached_to_struct.sol | 25 + ...ion_attached_to_struct_standard_input.json | 157 ++++ ...ernal_library_function_calling_private.sol | 25 + ...nction_calling_private_standard_input.json | 175 +++++ .../internal_library_function_pointer.sol | 15 + ...brary_function_pointer_standard_input.json | 193 +++++ ...ernal_library_function_return_var_size.sol | 25 + ...nction_return_var_size_standard_input.json | 82 ++ .../internal_types_in_library.sol | 27 + ...ernal_types_in_library_standard_input.json | 154 ++++ .../library_address.sol | 56 ++ .../library_address_standard_input.json | 97 +++ .../library_address_homestead.sol | 24 + ...rary_address_homestead_standard_input.json | 148 ++++ .../library_address_via_module.sol | 60 ++ ...ary_address_via_module_standard_input.json | 187 +++++ .../library_call_in_homestead.sol | 13 + ...rary_call_in_homestead_standard_input.json | 91 +++ .../library_delegatecall_guard_pure.sol | 32 + ...elegatecall_guard_pure_standard_input.json | 136 ++++ ...library_delegatecall_guard_view_needed.sol | 32 + ...call_guard_view_needed_standard_input.json | 115 +++ ...ary_delegatecall_guard_view_not_needed.sol | 31 + ..._guard_view_not_needed_standard_input.json | 64 ++ ...ary_delegatecall_guard_view_staticcall.sol | 31 + ..._guard_view_staticcall_standard_input.json | 178 +++++ .../library_enum_as_an_expression.sol | 13 + ..._enum_as_an_expression_standard_input.json | 55 ++ .../library_function_selectors.sol | 30 + ...ary_function_selectors_standard_input.json | 94 +++ .../library_function_selectors_struct.sol | 27 + ...ction_selectors_struct_standard_input.json | 52 ++ .../library_references_preserve.sol | 47 ++ ...ry_references_preserve_standard_input.json | 88 +++ .../library_return_struct_with_mapping.sol | 21 + ...rn_struct_with_mapping_standard_input.json | 73 ++ .../library_staticcall_delegatecall.sol | 18 + ...taticcall_delegatecall_standard_input.json | 196 +++++ .../library_stray_values.sol | 11 + .../library_stray_values_standard_input.json | 85 ++ .../library_struct_as_an_expression.sol | 16 + ...truct_as_an_expression_standard_input.json | 133 ++++ .../mapping_arguments_in_library.sol | 38 + ...g_arguments_in_library_standard_input.json | 139 ++++ .../mapping_returns_in_library.sol | 72 ++ ...ing_returns_in_library_standard_input.json | 166 ++++ .../mapping_returns_in_library_named.sol | 28 + ...turns_in_library_named_standard_input.json | 214 ++++++ .../payable_function_calls_library.sol | 11 + ...function_calls_library_standard_input.json | 40 + .../semanticTests/libraries_stub/stub.sol | 13 + .../libraries_stub/stub_standard_input.json | 205 +++++ .../libraries_stub_internal/stub_internal.sol | 12 + .../stub_internal_standard_input.json | 76 ++ .../using_for_by_name.sol | 13 + .../using_for_by_name_standard_input.json | 142 ++++ .../using_for_function_on_int.sol | 12 + ...ng_for_function_on_int_standard_input.json | 121 +++ .../using_for_overload.sol | 17 + .../using_for_overload_standard_input.json | 79 ++ .../using_for_storage_structs.sol | 25 + ...ng_for_storage_structs_standard_input.json | 37 + .../using_library_mappings_public.sol | 24 + ...ibrary_mappings_public_standard_input.json | 100 +++ .../using_library_mappings_return.sol | 22 + ...ibrary_mappings_return_standard_input.json | 61 ++ .../using_library_structs.sol | 24 + .../using_library_structs_standard_input.json | 160 ++++ .../literals_denominations/denominations.sol | 7 + .../denominations_standard_input.json | 43 ++ .../denominations_in_array_sizes.sol | 25 + ...nations_in_array_sizes_standard_input.json | 37 + .../semanticTests/literals_escape/escape.sol | 11 + .../escape_standard_input.json | 55 ++ .../semanticTests/literals_ether/ether.sol | 7 + .../literals_ether/ether_standard_input.json | 64 ++ .../fractional_denominations.sol | 15 + ...actional_denominations_standard_input.json | 52 ++ .../test/semanticTests/literals_gwei/gwei.sol | 7 + .../literals_gwei/gwei_standard_input.json | 61 ++ ...x_string_with_non_printable_characters.sol | 9 + ...n_printable_characters_standard_input.json | 40 + .../hex_string_with_underscore.sol | 7 + ...string_with_underscore_standard_input.json | 46 ++ .../scientific_notation.sol | 32 + .../scientific_notation_standard_input.json | 49 ++ ...y_operator_with_literal_types_overflow.sol | 17 + ...literal_types_overflow_standard_input.json | 58 ++ .../test/semanticTests/literals_wei/wei.sol | 7 + .../literals_wei/wei_standard_input.json | 34 + .../assembly_access.sol | 14 + .../assembly_access_standard_input.json | 37 + .../memory_types_initialisation.sol | 15 + ...y_types_initialisation_standard_input.json | 46 ++ .../return_variable.sol | 28 + .../return_variable_standard_input.json | 43 ++ .../static_memory_array_allocation.sol | 22 + ...emory_array_allocation_standard_input.json | 40 + .../struct_allocation.sol | 22 + .../struct_allocation_standard_input.json | 34 + .../name_other_contract.sol | 28 + .../name_other_contract_standard_input.json | 34 + .../access_through_contract_name.sol | 22 + ..._through_contract_name_standard_input.json | 55 ++ .../access_through_module_name.sol | 25 + ...ss_through_module_name_standard_input.json | 64 ++ .../break_in_modifier.sol | 20 + .../break_in_modifier_standard_input.json | 82 ++ .../continue_in_modifier.sol | 19 + .../continue_in_modifier_standard_input.json | 94 +++ .../evaluation_order.sol | 20 + .../evaluation_order_standard_input.json | 70 ++ .../function_modifier.sol | 12 + .../function_modifier_standard_input.json | 67 ++ ..._calling_functions_in_creation_context.sol | 48 ++ ...ns_in_creation_context_standard_input.json | 97 +++ .../function_modifier_empty.sol | 16 + ...unction_modifier_empty_standard_input.json | 34 + .../function_modifier_for_constructor.sol | 26 + ...difier_for_constructor_standard_input.json | 91 +++ .../function_modifier_library.sol | 27 + ...ction_modifier_library_standard_input.json | 118 +++ .../function_modifier_library_inheritance.sol | 33 + ...er_library_inheritance_standard_input.json | 43 ++ .../function_modifier_local_variables.sol | 18 + ...difier_local_variables_standard_input.json | 58 ++ .../function_modifier_loop.sol | 19 + ...function_modifier_loop_standard_input.json | 103 +++ .../function_modifier_loop_viair.sol | 14 + ...on_modifier_loop_viair_standard_input.json | 49 ++ .../function_modifier_multi_invocation.sol | 20 + ...ifier_multi_invocation_standard_input.json | 85 ++ ...nction_modifier_multi_invocation_viair.sol | 15 + ...multi_invocation_viair_standard_input.json | 121 +++ .../function_modifier_multi_with_return.sol | 23 + ...fier_multi_with_return_standard_input.json | 40 + .../function_modifier_multiple_times.sol | 14 + ...odifier_multiple_times_standard_input.json | 73 ++ ...ion_modifier_multiple_times_local_vars.sol | 17 + ...tiple_times_local_vars_standard_input.json | 115 +++ .../function_modifier_overriding.sol | 18 + ...on_modifier_overriding_standard_input.json | 61 ++ .../function_modifier_return_reference.sol | 13 + ...ifier_return_reference_standard_input.json | 79 ++ .../function_return_parameter.sol | 8 + ...ction_return_parameter_standard_input.json | 76 ++ .../function_return_parameter_complex.sol | 36 + ...turn_parameter_complex_standard_input.json | 112 +++ .../modifer_recursive.sol | 14 + .../modifer_recursive_standard_input.json | 106 +++ .../modifier_in_constructor_ice.sol | 5 + ...ier_in_constructor_ice_standard_input.json | 109 +++ .../modifier_init_return.sol | 12 + .../modifier_init_return_standard_input.json | 124 +++ .../modifiers_in_construction_context.sol | 11 + ...n_construction_context_standard_input.json | 100 +++ .../return_does_not_skip_modifier.sol | 15 + ...does_not_skip_modifier_standard_input.json | 88 +++ .../return_in_modifier.sol | 19 + .../return_in_modifier_standard_input.json | 37 + .../stacked_return_with_modifiers.sol | 21 + ..._return_with_modifiers_standard_input.json | 52 ++ .../transient_state_variable_value_type.sol | 18 + ...te_variable_value_type_standard_input.json | 46 ++ .../circular_import.sol | 13 + .../circular_import_standard_input.json | 70 ++ .../circular_import_2.sol | 14 + .../circular_import_2_standard_input.json | 46 ++ .../circular_reimport.sol | 16 + .../circular_reimport_standard_input.json | 43 ++ .../circular_reimport_2.sol | 16 + .../circular_reimport_2_standard_input.json | 67 ++ .../free_different_interger_types.sol | 12 + ...fferent_interger_types_standard_input.json | 61 ++ ...free_function_resolution_base_contract.sol | 16 + ...solution_base_contract_standard_input.json | 49 ++ ...e_function_resolution_override_virtual.sol | 16 + ...ution_override_virtual_standard_input.json | 40 + ...tion_resolution_override_virtual_super.sol | 16 + ...override_virtual_super_standard_input.json | 58 ++ ...resolution_override_virtual_transitive.sol | 23 + ...ide_virtual_transitive_standard_input.json | 52 ++ .../free_function_transitive_import.sol | 24 + ...tion_transitive_import_standard_input.json | 34 + .../multiSource_import/import.sol | 12 + .../import_standard_input.json | 37 + .../import_overloaded_function.sol | 13 + ...rt_overloaded_function_standard_input.json | 55 ++ .../imported_free_function_via_alias.sol | 17 + ...ree_function_via_alias_standard_input.json | 76 ++ ...ed_free_function_via_alias_direct_call.sol | 12 + ..._via_alias_direct_call_standard_input.json | 64 ++ .../reimport_imported_function.sol | 13 + ...port_imported_function_standard_input.json | 73 ++ .../compound_assign.sol | 20 + .../compound_assign_standard_input.json | 37 + .../compound_assign_transient_storage.sol | 22 + ...sign_transient_storage_standard_input.json | 34 + .../bitwise_shifting_constantinople.sol | 33 + ...hifting_constantinople_standard_input.json | 55 ++ ...twise_shifting_constantinople_combined.sol | 121 +++ ...onstantinople_combined_standard_input.json | 46 ++ ...wise_shifting_constants_constantinople.sol | 82 ++ ...nstants_constantinople_standard_input.json | 115 +++ .../shift_bytes_cleanup.sol | 19 + .../shift_bytes_cleanup_standard_input.json | 61 ++ .../shift_bytes_cleanup_viaYul.sol | 19 + ...t_bytes_cleanup_viaYul_standard_input.json | 49 ++ .../shift_cleanup.sol | 12 + .../shift_cleanup_standard_input.json | 67 ++ .../shift_cleanup_garbled.sol | 10 + .../shift_cleanup_garbled_standard_input.json | 82 ++ .../shift_constant_left.sol | 5 + .../shift_constant_left_standard_input.json | 64 ++ .../shift_constant_left_assignment.sol | 8 + ...nstant_left_assignment_standard_input.json | 151 ++++ .../shift_constant_right.sol | 5 + .../shift_constant_right_standard_input.json | 139 ++++ .../shift_constant_right_assignment.sol | 8 + ...stant_right_assignment_standard_input.json | 130 ++++ .../shift_left.sol | 12 + .../shift_left_standard_input.json | 106 +++ .../shift_left_assignment.sol | 13 + .../shift_left_assignment_standard_input.json | 133 ++++ .../shift_left_assignment_different_type.sol | 12 + ...ignment_different_type_standard_input.json | 145 ++++ .../shift_left_larger_type.sol | 10 + ...shift_left_larger_type_standard_input.json | 127 +++ .../shift_left_uint32.sol | 11 + .../shift_left_uint32_standard_input.json | 52 ++ .../shift_left_uint8.sol | 8 + .../shift_left_uint8_standard_input.json | 37 + .../shift_negative_constant_left.sol | 5 + ...negative_constant_left_standard_input.json | 85 ++ .../shift_negative_constant_right.sol | 5 + ...egative_constant_right_standard_input.json | 43 ++ .../shift_overflow.sol | 15 + .../shift_overflow_standard_input.json | 109 +++ .../shift_right.sol | 11 + .../shift_right_standard_input.json | 58 ++ .../shift_right_assignment.sol | 11 + ...shift_right_assignment_standard_input.json | 154 ++++ .../shift_right_garbled_signed_v1.sol | 32 + ...ight_garbled_signed_v1_standard_input.json | 157 ++++ .../shift_right_garbled_signed_v2.sol | 31 + ...ight_garbled_signed_v2_standard_input.json | 148 ++++ .../shift_right_garbled_v1.sol | 16 + ...shift_right_garbled_v1_standard_input.json | 40 + .../shift_right_garbled_v2.sol | 15 + ...shift_right_garbled_v2_standard_input.json | 34 + .../shift_right_negative_literal.sol | 62 ++ ...right_negative_literal_standard_input.json | 124 +++ .../shift_right_negative_lvalue.sol | 18 + ..._right_negative_lvalue_standard_input.json | 91 +++ ...shift_right_negative_lvalue_assignment.sol | 19 + ...tive_lvalue_assignment_standard_input.json | 97 +++ .../shift_right_negative_lvalue_int16.sol | 18 + ..._negative_lvalue_int16_standard_input.json | 103 +++ .../shift_right_negative_lvalue_int32.sol | 18 + ..._negative_lvalue_int32_standard_input.json | 112 +++ .../shift_right_negative_lvalue_int8.sol | 18 + ...t_negative_lvalue_int8_standard_input.json | 121 +++ ...ht_negative_lvalue_signextend_int16_v1.sol | 15 + ...ue_signextend_int16_v1_standard_input.json | 88 +++ ...ht_negative_lvalue_signextend_int16_v2.sol | 14 + ...ue_signextend_int16_v2_standard_input.json | 73 ++ ...ht_negative_lvalue_signextend_int32_v1.sol | 15 + ...ue_signextend_int32_v1_standard_input.json | 76 ++ ...ht_negative_lvalue_signextend_int32_v2.sol | 14 + ...ue_signextend_int32_v2_standard_input.json | 70 ++ ...ght_negative_lvalue_signextend_int8_v1.sol | 15 + ...lue_signextend_int8_v1_standard_input.json | 142 ++++ ...ght_negative_lvalue_signextend_int8_v2.sol | 14 + ...lue_signextend_int8_v2_standard_input.json | 136 ++++ .../shift_right_uint32.sol | 10 + .../shift_right_uint32_standard_input.json | 79 ++ .../shift_right_uint8.sol | 8 + .../shift_right_uint8_standard_input.json | 94 +++ .../shift_underflow_negative_rvalue.sol | 12 + ...erflow_negative_rvalue_standard_input.json | 118 +++ .../operators_shifts_shifts/shifts.sol | 9 + .../shifts_standard_input.json | 100 +++ ...t_storage_variable_increment_decrement.sol | 15 + ...le_increment_decrement_standard_input.json | 40 + .../all_possible_operators.sol | 92 +++ ...all_possible_operators_standard_input.json | 37 + ...ser_defined_value_types_with_operators.sol | 670 ++++++++++++++++ ...e_types_with_operators_standard_input.json | 49 ++ ...d_defining_operator_with_same_function.sol | 20 + ...tor_with_same_function_standard_input.json | 82 ++ .../checked_operators.sol | 22 + .../checked_operators_standard_input.json | 58 ++ .../consecutive_operator_invocations.sol | 18 + ...e_operator_invocations_standard_input.json | 67 ++ .../fixed_point_udvt_with_operators.sol | 22 + ...nt_udvt_with_operators_standard_input.json | 55 ++ ...ifferent_functions_separate_directives.sol | 26 + ...ns_separate_directives_standard_input.json | 64 ++ ...same_type_same_function_same_directive.sol | 20 + ...unction_same_directive_standard_input.json | 61 ++ ...definition_shadowing_builtin_keccak256.sol | 15 + ...wing_builtin_keccak256_standard_input.json | 34 + .../operator_evaluation_order.sol | 83 ++ ...rator_evaluation_order_standard_input.json | 70 ++ .../operator_making_pure_external_call.sol | 65 ++ ...ing_pure_external_call_standard_input.json | 52 ++ .../operator_making_view_external_call.sol | 71 ++ ...ing_view_external_call_standard_input.json | 40 + ...meter_and_return_cleanup_between_calls.sol | 22 + ..._cleanup_between_calls_standard_input.json | 76 ++ .../operator_parameter_cleanup.sol | 40 + ...ator_parameter_cleanup_standard_input.json | 85 ++ .../operator_precendence.sol | 71 ++ .../operator_precendence_standard_input.json | 79 ++ .../operator_return_parameter_cleanup.sol | 58 ++ ...turn_parameter_cleanup_standard_input.json | 43 ++ .../recursive_operator.sol | 41 + .../recursive_operator_standard_input.json | 73 ++ .../unchecked_operators.sol | 24 + .../unchecked_operators_standard_input.json | 46 ++ .../optimizer_shift_bytes/shift_bytes.sol | 42 + .../shift_bytes_standard_input.json | 34 + ...o_nonpayable_circumvention_by_modifier.sol | 14 + ...cumvention_by_modifier_standard_input.json | 34 + .../empty_calldata_calls_receive.sol | 13 + ...calldata_calls_receive_standard_input.json | 34 + .../receive_ether_and_data/ether_and_data.sol | 6 + .../ether_and_data_standard_input.json | 40 + .../receive_inherited/inherited.sol | 12 + .../inherited_standard_input.json | 37 + .../array_slices.sol | 11 + .../array_slices_standard_input.json | 85 ++ .../revertStrings_bubble/bubble.sol | 15 + .../bubble_standard_input.json | 64 ++ .../calldata_array_dynamic_invalid.sol | 11 + ..._array_dynamic_invalid_standard_input.json | 58 ++ ...data_array_dynamic_static_short_decode.sol | 12 + ...ic_static_short_decode_standard_input.json | 67 ++ ...ta_array_dynamic_static_short_reencode.sol | 14 + ..._static_short_reencode_standard_input.json | 97 +++ .../calldata_array_invalid_length.sol | 11 + ...a_array_invalid_length_standard_input.json | 82 ++ .../calldata_arrays_too_large.sol | 11 + ...ldata_arrays_too_large_standard_input.json | 79 ++ .../calldata_tail_short.sol | 9 + .../calldata_tail_short_standard_input.json | 88 +++ .../calldata_too_short_v1.sol | 13 + .../calldata_too_short_v1_standard_input.json | 37 + .../called_contract_has_code.sol | 12 + ...lled_contract_has_code_standard_input.json | 100 +++ .../revertStrings_empty_v1/empty_v1.sol | 18 + .../empty_v1_standard_input.json | 40 + .../revertStrings_empty_v2/empty_v2.sol | 17 + .../empty_v2_standard_input.json | 49 ++ .../revertStrings_enum_v1/enum_v1.sol | 14 + .../enum_v1_standard_input.json | 46 ++ .../revertStrings_enum_v2/enum_v2.sol | 12 + .../enum_v2_standard_input.json | 55 ++ .../ether_non_payable_function.sol | 9 + ...r_non_payable_function_standard_input.json | 52 ++ .../function_entry_checks_v1.sol | 11 + ...nction_entry_checks_v1_standard_input.json | 91 +++ .../function_entry_checks_v2.sol | 9 + ...nction_entry_checks_v2_standard_input.json | 103 +++ .../invalid_abi_decoding_calldata_v1.sol | 15 + ...i_decoding_calldata_v1_standard_input.json | 73 ++ .../invalid_abi_decoding_memory_v1.sol | 22 + ...abi_decoding_memory_v1_standard_input.json | 76 ++ .../library_non_view_call.sol | 16 + .../library_non_view_call_standard_input.json | 70 ++ .../short_input_array.sol | 9 + .../short_input_array_standard_input.json | 94 +++ .../short_input_bytes.sol | 9 + .../short_input_bytes_standard_input.json | 34 + .../revertStrings_transfer/transfer.sol | 27 + .../transfer_standard_input.json | 61 ++ .../unknown_sig_no_fallback.sol | 8 + ...nknown_sig_no_fallback_standard_input.json | 43 ++ .../reverts_assert_require/assert_require.sol | 21 + .../assert_require_standard_input.json | 58 ++ .../reverts_error_struct/error_struct.sol | 15 + .../error_struct_standard_input.json | 37 + .../invalid_enum_as_external_arg.sol | 21 + ...d_enum_as_external_arg_standard_input.json | 52 ++ .../invalid_enum_as_external_ret.sol | 31 + ...d_enum_as_external_ret_standard_input.json | 55 ++ .../invalid_enum_compared.sol | 30 + .../invalid_enum_compared_standard_input.json | 40 + .../invalid_enum_stored.sol | 24 + .../invalid_enum_stored_standard_input.json | 34 + .../invalid_instruction.sol | 9 + .../invalid_instruction_standard_input.json | 49 ++ .../semanticTests/reverts_revert/revert.sol | 20 + .../reverts_revert/revert_standard_input.json | 43 ++ .../revert_return_area.sol | 18 + .../revert_return_area_standard_input.json | 46 ++ .../reverts_simple_throw/simple_throw.sol | 10 + .../simple_throw_standard_input.json | 61 ++ .../prediction_example.sol | 30 + .../prediction_example_standard_input.json | 40 + .../salted_create.sol | 29 + .../salted_create_standard_input.json | 34 + .../salted_create_with_value.sol | 29 + ...lted_create_with_value_standard_input.json | 37 + .../evmone_support.sol | 31 + .../evmone_support_standard_input.json | 37 + .../semanticTests/shanghai_push0/push0.sol | 11 + .../shanghai_push0/push0_standard_input.json | 34 + .../smoke_alignment/alignment.sol | 30 + .../alignment_standard_input.json | 43 ++ .../semanticTests/smoke_arrays/arrays.sol | 43 ++ .../smoke_arrays/arrays_standard_input.json | 46 ++ .../test/semanticTests/smoke_basic/basic.sol | 41 + .../smoke_basic/basic_standard_input.json | 52 ++ .../bytes_and_strings.sol | 21 + .../bytes_and_strings_standard_input.json | 58 ++ .../smoke_constructor/constructor.sol | 25 + .../constructor_standard_input.json | 49 ++ .../semanticTests/smoke_failure/failure.sol | 24 + .../smoke_failure/failure_standard_input.json | 61 ++ .../semanticTests/smoke_fallback/fallback.sol | 23 + .../fallback_standard_input.json | 55 ++ .../smoke_multiline/multiline.sol | 13 + .../multiline_standard_input.json | 34 + .../multiline_comments.sol | 17 + .../multiline_comments_standard_input.json | 37 + .../semanticTests/smoke_structs/structs.sol | 22 + .../smoke_structs/structs_standard_input.json | 40 + .../abi_encode_with_signature_from_string.sol | 12 + ..._signature_from_string_standard_input.json | 34 + .../abi_functions_member_access.sol | 11 + ...unctions_member_access_standard_input.json | 40 + .../keccak256_optimized.sol | 17 + .../keccak256_optimized_standard_input.json | 37 + .../semanticTests/state_blobhash/blobhash.sol | 14 + .../blobhash_standard_input.json | 82 ++ .../state_block_basefee/block_basefee.sol | 17 + .../block_basefee_standard_input.json | 79 ++ .../block_blobbasefee.sol | 17 + .../block_blobbasefee_standard_input.json | 61 ++ .../state_block_chainid/block_chainid.sol | 11 + .../block_chainid_standard_input.json | 34 + .../state_block_coinbase/block_coinbase.sol | 9 + .../block_coinbase_standard_input.json | 64 ++ .../block_difficulty.sol | 11 + .../block_difficulty_standard_input.json | 73 ++ .../block_difficulty_post_paris.sol | 11 + ..._difficulty_post_paris_standard_input.json | 46 ++ .../state_block_gaslimit/block_gaslimit.sol | 9 + .../block_gaslimit_standard_input.json | 52 ++ .../state_block_number/block_number.sol | 10 + .../block_number_standard_input.json | 97 +++ .../block_prevrandao.sol | 9 + .../block_prevrandao_standard_input.json | 85 ++ .../block_prevrandao_pre_paris.sol | 9 + ...k_prevrandao_pre_paris_standard_input.json | 88 +++ .../state_block_timestamp/block_timestamp.sol | 10 + .../block_timestamp_standard_input.json | 76 ++ .../state_blockhash_basic/blockhash_basic.sol | 27 + .../blockhash_basic_standard_input.json | 58 ++ .../semanticTests/state_gasleft/gasleft.sol | 9 + .../state_gasleft/gasleft_standard_input.json | 70 ++ .../semanticTests/state_msg_data/msg_data.sol | 11 + .../msg_data_standard_input.json | 49 ++ .../state_msg_sender/msg_sender.sol | 7 + .../msg_sender_standard_input.json | 40 + .../semanticTests/state_msg_sig/msg_sig.sol | 11 + .../state_msg_sig/msg_sig_standard_input.json | 55 ++ .../state_msg_value/msg_value.sol | 8 + .../msg_value_standard_input.json | 91 +++ .../state_tx_gasprice/tx_gasprice.sol | 9 + .../tx_gasprice_standard_input.json | 94 +++ .../state_tx_origin/tx_origin.sol | 9 + .../tx_origin_standard_input.json | 67 ++ .../uncalled_blobhash.sol | 12 + .../uncalled_blobhash_standard_input.json | 43 ++ .../uncalled_blockhash.sol | 7 + .../uncalled_blockhash_standard_input.json | 37 + .../state_var_initialization.sol | 12 + ...ate_var_initialization_standard_input.json | 94 +++ .../state_variables_init_order.sol | 12 + ...e_variables_init_order_standard_input.json | 43 ++ .../state_variables_init_order_2.sol | 16 + ...variables_init_order_2_standard_input.json | 64 ++ .../state_variables_init_order_3.sol | 29 + ...variables_init_order_3_standard_input.json | 61 ++ .../do_while_loop_continue.sol | 14 + ...do_while_loop_continue_standard_input.json | 34 + .../accessors_mapping_for_array.sol | 15 + ...sors_mapping_for_array_standard_input.json | 79 ++ .../storage_array_accessor/array_accessor.sol | 33 + .../array_accessor_standard_input.json | 85 ++ .../storage_chop_sign_bits/chop_sign_bits.sol | 29 + .../chop_sign_bits_standard_input.json | 58 ++ .../complex_accessors.sol | 17 + .../complex_accessors_standard_input.json | 70 ++ .../empty_nonempty_empty.sol | 32 + .../empty_nonempty_empty_standard_input.json | 37 + .../storage_mapping_state/mapping_state.sol | 44 ++ .../mapping_state_standard_input.json | 76 ++ .../mapping_string_key.sol | 22 + .../mapping_string_key_standard_input.json | 46 ++ .../mappings_array2d_pop_delete.sol | 39 + ...ngs_array2d_pop_delete_standard_input.json | 40 + .../mappings_array_pop_delete.sol | 34 + ...pings_array_pop_delete_standard_input.json | 61 ++ .../packed_functions.sol | 47 ++ .../packed_functions_standard_input.json | 82 ++ .../packed_storage_overflow.sol | 15 + ...acked_storage_overflow_standard_input.json | 49 ++ .../packed_storage_signed.sol | 23 + .../packed_storage_signed_standard_input.json | 52 ++ .../packed_storage_structs_bytes.sol | 47 ++ ..._storage_structs_bytes_standard_input.json | 55 ++ .../packed_storage_structs_enum.sol | 32 + ...d_storage_structs_enum_standard_input.json | 64 ++ .../packed_storage_structs_uint.sol | 29 + ...d_storage_structs_uint_standard_input.json | 73 ++ .../simple_accessor.sol | 8 + .../simple_accessor_standard_input.json | 43 ++ .../state_smoke_test.sol | 21 + .../state_smoke_test_standard_input.json | 67 ++ .../struct_accessor.sol | 12 + .../struct_accessor_standard_input.json | 34 + .../string_concat_2_args.sol | 12 + .../string_concat_2_args_standard_input.json | 40 + .../string_concat_different_types.sol | 35 + ...concat_different_types_standard_input.json | 46 ++ .../string_concat_empty_argument_list.sol | 7 + ...at_empty_argument_list_standard_input.json | 43 ++ .../string_concat_empty_strings.sol | 24 + ...g_concat_empty_strings_standard_input.json | 34 + .../string_concat_nested.sol | 7 + .../string_concat_nested_standard_input.json | 37 + .../constant_string_literal.sol | 23 + ...onstant_string_literal_standard_input.json | 55 ++ .../empty_storage_string.sol | 100 +++ .../empty_storage_string_standard_input.json | 46 ++ .../strings_empty_string/empty_string.sol | 7 + .../empty_string_standard_input.json | 52 ++ .../empty_string_input.sol | 28 + .../empty_string_input_standard_input.json | 43 ++ .../strings_return_string/return_string.sol | 17 + .../return_string_standard_input.json | 49 ++ .../strings_string_escapes/string_escapes.sol | 8 + .../string_escapes_standard_input.json | 34 + .../unicode_escapes.sol | 22 + .../unicode_escapes_standard_input.json | 37 + .../strings_unicode_string/unicode_string.sol | 12 + .../unicode_string_standard_input.json | 40 + .../array_of_recursive_struct.sol | 12 + ...ay_of_recursive_struct_standard_input.json | 142 ++++ .../calldata_nested_structs.sol | 47 ++ ...alldata_nested_structs_standard_input.json | 73 ++ .../calldata_struct.sol | 16 + .../calldata_struct_standard_input.json | 37 + .../calldata_struct_and_ints.sol | 19 + ...lldata_struct_and_ints_standard_input.json | 46 ++ .../calldata_struct_array_member.sol | 23 + ...ta_struct_array_member_standard_input.json | 64 ++ .../calldata_struct_array_member_dynamic.sol | 22 + ...t_array_member_dynamic_standard_input.json | 79 ++ ...ata_struct_as_argument_of_lib_function.sol | 27 + ...gument_of_lib_function_standard_input.json | 52 ++ .../calldata_struct_as_memory_argument.sol | 21 + ...uct_as_memory_argument_standard_input.json | 76 ++ .../calldata_struct_struct_member.sol | 26 + ...a_struct_struct_member_standard_input.json | 70 ++ .../calldata_struct_struct_member_dynamic.sol | 26 + ..._struct_member_dynamic_standard_input.json | 58 ++ .../calldata_struct_to_memory.sol | 16 + ...ldata_struct_to_memory_standard_input.json | 85 ++ ...data_struct_to_memory_tuple_assignment.sol | 20 + ...emory_tuple_assignment_standard_input.json | 40 + .../calldata_struct_to_storage.sol | 19 + ...data_struct_to_storage_standard_input.json | 34 + .../calldata_struct_with_array_to_memory.sol | 20 + ...t_with_array_to_memory_standard_input.json | 61 ++ .../calldata_struct_with_bytes_to_memory.sol | 20 + ...t_with_bytes_to_memory_standard_input.json | 67 ++ ...ata_struct_with_nested_array_to_memory.sol | 21 + ...nested_array_to_memory_standard_input.json | 82 ++ ...ta_struct_with_nested_array_to_storage.sol | 21 + ...ested_array_to_storage_standard_input.json | 55 ++ .../calldata_structs.sol | 26 + .../calldata_structs_standard_input.json | 43 ++ .../dynamic_nested.sol | 11 + .../dynamic_nested_standard_input.json | 49 ++ .../dynamically_encoded.sol | 10 + .../dynamically_encoded_standard_input.json | 88 +++ .../recursive_storage_memory.sol | 28 + ...cursive_storage_memory_standard_input.json | 34 + .../recursive_storage_memory_complex.sol | 50 ++ ...storage_memory_complex_standard_input.json | 37 + .../copy_from_mapping.sol | 43 ++ .../copy_from_mapping_standard_input.json | 37 + .../copy_from_storage.sol | 22 + .../copy_from_storage_standard_input.json | 43 ++ .../copy_struct_array_from_storage.sol | 95 +++ ...uct_array_from_storage_standard_input.json | 133 ++++ ...h_nested_array_from_calldata_to_memory.sol | 15 + ...rom_calldata_to_memory_standard_input.json | 130 ++++ ..._nested_array_from_calldata_to_storage.sol | 21 + ...om_calldata_to_storage_standard_input.json | 118 +++ ...ith_nested_array_from_memory_to_memory.sol | 15 + ..._from_memory_to_memory_standard_input.json | 172 +++++ ...h_nested_array_from_storage_to_storage.sol | 26 + ...rom_storage_to_storage_standard_input.json | 115 +++ .../copy_substructures_from_mapping.sol | 51 ++ ...tructures_from_mapping_standard_input.json | 46 ++ .../copy_substructures_to_mapping.sol | 65 ++ ...bstructures_to_mapping_standard_input.json | 157 ++++ .../copy_to_mapping.sol | 62 ++ .../copy_to_mapping_standard_input.json | 139 ++++ .../structs_delete_struct/delete_struct.sol | 48 ++ .../delete_struct_standard_input.json | 166 ++++ .../semanticTests/structs_event/event.sol | 16 + .../structs_event/event_standard_input.json | 70 ++ .../function_type_copy.sol | 43 ++ .../function_type_copy_standard_input.json | 103 +++ .../semanticTests/structs_global/global.sol | 10 + .../structs_global/global_standard_input.json | 61 ++ .../lone_struct_array_type.sol | 13 + ...lone_struct_array_type_standard_input.json | 181 +++++ .../memory_struct_named_constructor.sol | 15 + ...ruct_named_constructor_standard_input.json | 34 + .../memory_structs_as_function_args.sol | 31 + ...ructs_as_function_args_standard_input.json | 76 ++ .../memory_structs_nested.sol | 41 + .../memory_structs_nested_standard_input.json | 124 +++ .../memory_structs_nested_load.sol | 72 ++ ...ry_structs_nested_load_standard_input.json | 106 +++ .../memory_structs_read_write.sol | 55 ++ ...ory_structs_read_write_standard_input.json | 91 +++ .../msg_data_to_struct_member_copy.sol | 43 ++ ..._to_struct_member_copy_standard_input.json | 97 +++ .../multislot_struct_allocation.sol | 19 + ...slot_struct_allocation_standard_input.json | 154 ++++ .../nested_struct_allocation.sol | 16 + ...sted_struct_allocation_standard_input.json | 121 +++ .../packed_storage_structs_delete.sol | 25 + ...storage_structs_delete_standard_input.json | 178 +++++ .../recursive_struct_2.sol | 24 + .../recursive_struct_2_standard_input.json | 85 ++ .../recursive_structs.sol | 18 + .../recursive_structs_standard_input.json | 136 ++++ .../simple_struct_allocation.sol | 12 + ...mple_struct_allocation_standard_input.json | 67 ++ .../struct_assign_reference_to_struct.sol | 35 + ...gn_reference_to_struct_standard_input.json | 148 ++++ .../struct_constructor_nested.sol | 30 + ...uct_constructor_nested_standard_input.json | 160 ++++ ...truct_containing_bytes_copy_and_delete.sol | 39 + ..._bytes_copy_and_delete_standard_input.json | 73 ++ .../structs_struct_copy/struct_copy.sol | 52 ++ .../struct_copy_standard_input.json | 163 ++++ .../struct_copy_via_local.sol | 22 + .../struct_copy_via_local_standard_input.json | 94 +++ .../struct_delete_member.sol | 19 + .../struct_delete_member_standard_input.json | 82 ++ .../struct_delete_storage.sol | 21 + .../struct_delete_storage_standard_input.json | 88 +++ .../struct_delete_storage_nested_small.sol | 36 + ...e_storage_nested_small_standard_input.json | 40 + .../struct_delete_storage_small.sol | 24 + ...t_delete_storage_small_standard_input.json | 175 +++++ .../struct_delete_storage_with_array.sol | 51 ++ ...ete_storage_with_array_standard_input.json | 109 +++ ...truct_delete_storage_with_arrays_small.sol | 30 + ...rage_with_arrays_small_standard_input.json | 184 +++++ .../struct_delete_struct_in_mapping.sol | 17 + ...lete_struct_in_mapping_standard_input.json | 145 ++++ .../struct_memory_to_storage.sol | 25 + ...ruct_memory_to_storage_standard_input.json | 64 ++ .../struct_memory_to_storage_function_ptr.sol | 33 + ...o_storage_function_ptr_standard_input.json | 112 +++ .../struct_named_constructor.sol | 13 + ...ruct_named_constructor_standard_input.json | 52 ++ .../struct_reference.sol | 24 + .../struct_reference_standard_input.json | 49 ++ .../struct_referencing.sol | 58 ++ .../struct_referencing_standard_input.json | 79 ++ .../struct_storage_push_zero_value.sol | 26 + ...torage_push_zero_value_standard_input.json | 100 +++ .../struct_storage_to_mapping.sol | 15 + ...uct_storage_to_mapping_standard_input.json | 151 ++++ .../struct_storage_to_memory.sol | 23 + ...ruct_storage_to_memory_standard_input.json | 169 ++++ .../struct_storage_to_memory_function_ptr.sol | 29 + ...to_memory_function_ptr_standard_input.json | 127 +++ .../semanticTests/structs_structs/structs.sol | 36 + .../structs_standard_input.json | 58 ++ .../using_for_function_on_struct.sol | 13 + ...for_function_on_struct_standard_input.json | 55 ++ .../semanticTests/tryCatch_assert/assert.sol | 16 + .../assert_standard_input.json | 55 ++ .../semanticTests/tryCatch_create/create.sol | 32 + .../create_standard_input.json | 40 + .../invalid_error_encoding.sol | 168 ++++ ...invalid_error_encoding_standard_input.json | 70 ++ .../tryCatch_lowLevel/lowLevel.sol | 18 + .../lowLevel_standard_input.json | 88 +++ .../malformed_error.sol | 88 +++ .../malformed_error_standard_input.json | 46 ++ .../malformed_panic.sol | 54 ++ .../malformed_panic_standard_input.json | 61 ++ .../malformed_panic_2.sol | 52 ++ .../malformed_panic_2_standard_input.json | 82 ++ .../malformed_panic_3.sol | 58 ++ .../malformed_panic_3_standard_input.json | 85 ++ .../malformed_panic_4.sol | 61 ++ .../malformed_panic_4_standard_input.json | 73 ++ .../semanticTests/tryCatch_nested/nested.sol | 33 + .../nested_standard_input.json | 34 + .../semanticTests/tryCatch_panic/panic.sol | 33 + .../tryCatch_panic/panic_standard_input.json | 49 ++ .../return_function.sol | 17 + .../return_function_standard_input.json | 76 ++ .../semanticTests/tryCatch_simple/simple.sol | 18 + .../simple_standard_input.json | 67 ++ .../simple_notuple.sol | 18 + .../simple_notuple_standard_input.json | 43 ++ .../tryCatch_structured/structured.sol | 19 + .../structured_standard_input.json | 64 ++ .../structuredAndLowLevel.sol | 23 + .../structuredAndLowLevel_standard_input.json | 58 ++ .../tryCatch_super_trivial/super_trivial.sol | 17 + .../super_trivial_standard_input.json | 52 ++ .../tryCatch_trivial/trivial.sol | 16 + .../trivial_standard_input.json | 37 + .../try_catch_library_call.sol | 45 ++ ...try_catch_library_call_standard_input.json | 79 ++ ...ray_mapping_abstract_constructor_param.sol | 17 + ...ract_constructor_param_standard_input.json | 79 ++ .../assign_calldata_value_type.sol | 9 + ...gn_calldata_value_type_standard_input.json | 43 ++ ...ixed_bytes_to_fixed_bytes_greater_size.sol | 7 + ...xed_bytes_greater_size_standard_input.json | 109 +++ ...t_fixed_bytes_to_fixed_bytes_same_size.sol | 7 + ..._fixed_bytes_same_size_standard_input.json | 118 +++ ...ixed_bytes_to_fixed_bytes_smaller_size.sol | 7 + ...xed_bytes_smaller_size_standard_input.json | 121 +++ ...nvert_fixed_bytes_to_uint_greater_size.sol | 7 + ...s_to_uint_greater_size_standard_input.json | 70 ++ ...vert_fixed_bytes_to_uint_same_min_size.sol | 7 + ..._to_uint_same_min_size_standard_input.json | 85 ++ .../convert_fixed_bytes_to_uint_same_type.sol | 7 + ...ytes_to_uint_same_type_standard_input.json | 61 ++ ...nvert_fixed_bytes_to_uint_smaller_size.sol | 7 + ...s_to_uint_smaller_size_standard_input.json | 73 ++ ...nvert_uint_to_fixed_bytes_greater_size.sol | 7 + ...xed_bytes_greater_size_standard_input.json | 34 + ...vert_uint_to_fixed_bytes_same_min_size.sol | 7 + ...ed_bytes_same_min_size_standard_input.json | 91 +++ .../convert_uint_to_fixed_bytes_same_size.sol | 7 + ..._fixed_bytes_same_size_standard_input.json | 64 ++ ...nvert_uint_to_fixed_bytes_smaller_size.sol | 7 + ...xed_bytes_smaller_size_standard_input.json | 46 ++ .../external_function_to_address.sol | 11 + ...al_function_to_address_standard_input.json | 58 ++ .../mapping_abstract_constructor_param.sol | 15 + ...ract_constructor_param_standard_input.json | 37 + .../mapping_contract_key.sol | 26 + .../mapping_contract_key_standard_input.json | 112 +++ .../mapping_contract_key_getter.sol | 38 + ...ng_contract_key_getter_standard_input.json | 52 ++ .../mapping_contract_key_library.sol | 35 + ...g_contract_key_library_standard_input.json | 67 ++ .../copy_from_mapping_to_mapping.sol | 34 + ...rom_mapping_to_mapping_standard_input.json | 37 + ...copy_struct_to_array_stored_in_mapping.sol | 56 ++ ...rray_stored_in_mapping_standard_input.json | 34 + .../mapping_enum_key_getter_v1.sol | 43 ++ ...ing_enum_key_getter_v1_standard_input.json | 76 ++ .../mapping_enum_key_getter_v2.sol | 39 + ...ing_enum_key_getter_v2_standard_input.json | 82 ++ .../mapping_enum_key_library_v1.sol | 40 + ...ng_enum_key_library_v1_standard_input.json | 94 +++ .../mapping_enum_key_library_v2.sol | 39 + ...ng_enum_key_library_v2_standard_input.json | 103 +++ .../mapping_enum_key_v1.sol | 33 + .../mapping_enum_key_v1_standard_input.json | 40 + .../mapping_enum_key_v2.sol | 31 + .../mapping_enum_key_v2_standard_input.json | 49 ++ .../types_mapping_simple/mapping_simple.sol | 25 + .../mapping_simple_standard_input.json | 97 +++ .../user_defined_types_mapping_storage.sol | 25 + ..._types_mapping_storage_standard_input.json | 40 + .../types_nested_tuples/nested_tuples.sol | 34 + .../nested_tuples_standard_input.json | 88 +++ .../packing_signed_types.sol | 8 + .../packing_signed_types_standard_input.json | 55 ++ .../packing_unpacking_types.sol | 10 + ...acking_unpacking_types_standard_input.json | 124 +++ .../semanticTests/types_strings/strings.sol | 16 + .../types_strings/strings_standard_input.json | 100 +++ ...uct_mapping_abstract_constructor_param.sol | 24 + ...ract_constructor_param_standard_input.json | 106 +++ .../tuple_assign_multi_slot_grow.sol | 11 + ...assign_multi_slot_grow_standard_input.json | 115 +++ .../type_conversion_cleanup.sol | 5 + ...ype_conversion_cleanup_standard_input.json | 127 +++ .../underscore_as_function/as_function.sol | 18 + .../as_function_standard_input.json | 34 + .../invalidInConstructor.sol | 23 + .../invalidInConstructor_standard_input.json | 46 ++ .../invalidStoredInConstructor.sol | 23 + ...lidStoredInConstructor_standard_input.json | 49 ++ .../store2.sol | 39 + .../store2_standard_input.json | 34 + .../storeInConstructor.sol | 19 + .../storeInConstructor_standard_input.json | 40 + ...lized_internal_storage_function_legacy.sol | 17 + ...torage_function_legacy_standard_input.json | 37 + ...ized_internal_storage_function_via_yul.sol | 17 + ...orage_function_via_yul_standard_input.json | 43 ++ .../unused_store_storage_removal_bug.sol | 15 + ...re_storage_removal_bug_standard_input.json | 67 ++ .../abicodec.sol | 35 + .../abicodec_standard_input.json | 61 ++ .../assembly_access_bytes2_abicoder_v1.sol | 35 + ...ess_bytes2_abicoder_v1_standard_input.json | 106 +++ .../assembly_access_bytes2_abicoder_v2.sol | 33 + ...ess_bytes2_abicoder_v2_standard_input.json | 100 +++ .../calldata.sol | 63 ++ .../calldata_standard_input.json | 85 ++ .../calldata_to_storage.sol | 41 + .../calldata_to_storage_standard_input.json | 82 ++ .../userDefinedValueType_cleanup/cleanup.sol | 41 + .../cleanup_standard_input.json | 73 ++ .../cleanup_abicoderv1.sol | 43 ++ .../cleanup_abicoderv1_standard_input.json | 88 +++ .../constant.sol | 11 + .../constant_standard_input.json | 40 + .../conversion.sol | 54 ++ .../conversion_standard_input.json | 49 ++ .../conversion_abicoderv1.sol | 56 ++ .../conversion_abicoderv1_standard_input.json | 58 ++ .../dirty_slot.sol | 35 + .../dirty_slot_standard_input.json | 79 ++ .../dirty_uint8_read.sol | 24 + .../dirty_uint8_read_standard_input.json | 52 ++ .../userDefinedValueType_erc20/erc20.sol | 148 ++++ .../erc20_standard_input.json | 46 ++ .../fixedpoint.sol | 54 ++ .../fixedpoint_standard_input.json | 64 ++ .../immutable_signed.sol | 19 + .../immutable_signed_standard_input.json | 118 +++ .../in_parenthesis.sol | 11 + .../in_parenthesis_standard_input.json | 109 +++ .../mapping_key.sol | 16 + .../mapping_key_standard_input.json | 70 ++ .../memory_to_storage.sol | 41 + .../memory_to_storage_standard_input.json | 76 ++ .../multisource.sol | 12 + .../multisource_standard_input.json | 115 +++ .../multisource_module.sol | 11 + .../multisource_module_standard_input.json | 112 +++ .../userDefinedValueType_ownable/ownable.sol | 30 + .../ownable_standard_input.json | 55 ++ .../parameter.sol | 40 + .../parameter_standard_input.json | 103 +++ .../userDefinedValueType_simple/simple.sol | 12 + .../simple_standard_input.json | 91 +++ .../storage_layout.sol | 72 ++ .../storage_layout_standard_input.json | 67 ++ .../storage_layout_struct.sol | 178 +++++ .../storage_layout_struct_standard_input.json | 43 ++ .../storage_signed.sol | 33 + .../storage_signed_standard_input.json | 97 +++ .../wrap_unwrap.sol | 9 + .../wrap_unwrap_standard_input.json | 94 +++ .../wrap_unwrap_via_contract_name.sol | 22 + ...wrap_via_contract_name_standard_input.json | 121 +++ ...cost_abstraction_comparison_elementary.sol | 34 + ..._comparison_elementary_standard_input.json | 37 + ...ost_abstraction_comparison_userdefined.sol | 35 + ...comparison_userdefined_standard_input.json | 34 + .../calldata_memory_copy.sol | 17 + .../calldata_memory_copy_standard_input.json | 49 ++ .../free_function_braces.sol | 24 + .../free_function_braces_standard_input.json | 70 ++ .../free_function_multi.sol | 24 + .../free_function_multi_standard_input.json | 37 + .../free_functions_individual.sol | 26 + ...e_functions_individual_standard_input.json | 40 + .../imported_functions.sol | 17 + .../imported_functions_standard_input.json | 73 ++ .../library_functions_inside_contract.sol | 31 + ...ctions_inside_contract_standard_input.json | 55 ++ .../library_on_interface.sol | 16 + .../library_on_interface_standard_input.json | 58 ++ .../library_through_module.sol | 32 + ...library_through_module_standard_input.json | 52 ++ .../using_module_renamed/module_renamed.sol | 24 + .../module_renamed_standard_input.json | 46 ++ .../private_library_function.sol | 10 + ...ivate_library_function_standard_input.json | 64 ++ .../recursive_import.sol | 23 + .../recursive_import_standard_input.json | 76 ++ .../using_global_all_the_types.sol | 36 + ...g_global_all_the_types_standard_input.json | 67 ++ .../using_global_for_global.sol | 17 + ...sing_global_for_global_standard_input.json | 43 ++ .../using_global_invisible.sol | 44 ++ ...using_global_invisible_standard_input.json | 34 + .../using_global_library.sol | 25 + .../using_global_library_standard_input.json | 61 ++ .../variables_delete_local/delete_local.sol | 9 + .../delete_local_standard_input.json | 73 ++ .../variables_delete_locals/delete_locals.sol | 12 + .../delete_locals_standard_input.json | 79 ++ .../delete_transient_state_variable.sol | 12 + ...ansient_state_variable_standard_input.json | 34 + ...ansient_state_variable_non_zero_offset.sol | 17 + ...riable_non_zero_offset_standard_input.json | 49 ++ .../mapping_local_assignment.sol | 15 + ...pping_local_assignment_standard_input.json | 61 ++ .../mapping_local_compound_assignment.sol | 14 + ...al_compound_assignment_standard_input.json | 52 ++ .../mapping_local_tuple_assignment.sol | 16 + ...local_tuple_assignment_standard_input.json | 64 ++ .../public_state_overridding.sol | 17 + ...blic_state_overridding_standard_input.json | 43 ++ ...ublic_state_overridding_dynamic_struct.sol | 22 + ...ridding_dynamic_struct_standard_input.json | 94 +++ ..._overridding_mapping_to_dynamic_struct.sol | 24 + ...ping_to_dynamic_struct_standard_input.json | 67 ++ .../storing_invalid_boolean.sol | 33 + ...toring_invalid_boolean_standard_input.json | 82 ++ ...transient_function_type_state_variable.sol | 16 + ...on_type_state_variable_standard_input.json | 46 ++ ...ansient_state_address_variable_members.sol | 20 + ...dress_variable_members_standard_input.json | 70 ++ .../transient_state_enum_variable.sol | 17 + ...nt_state_enum_variable_standard_input.json | 91 +++ .../transient_state_variable.sol | 21 + ...ansient_state_variable_standard_input.json | 55 ++ ...ient_state_variable_cleanup_assignment.sol | 16 + ...ble_cleanup_assignment_standard_input.json | 37 + ...ransient_state_variable_cleanup_tstore.sol | 14 + ...ariable_cleanup_tstore_standard_input.json | 58 ++ ...nt_state_variable_slot_inline_assembly.sol | 31 + ...e_slot_inline_assembly_standard_input.json | 76 ++ ...sient_state_variable_slots_and_offsets.sol | 20 + ...able_slots_and_offsets_standard_input.json | 85 ++ ...nsient_state_variable_tuple_assignment.sol | 20 + ...iable_tuple_assignment_standard_input.json | 40 + .../transient_state_variable_udvt.sol | 22 + ...nt_state_variable_udvt_standard_input.json | 88 +++ .../various_address_code/address_code.sol | 26 + .../address_code_standard_input.json | 112 +++ .../address_code_complex.sol | 17 + .../address_code_complex_standard_input.json | 187 +++++ ...ment_to_const_var_involving_expression.sol | 9 + ...r_involving_expression_standard_input.json | 226 ++++++ .../semanticTests/various_balance/balance.sol | 10 + .../balance_standard_input.json | 199 +++++ .../byte_optimization_bug.sol | 16 + .../byte_optimization_bug_standard_input.json | 55 ++ .../code_access_content.sol | 45 ++ .../code_access_content_standard_input.json | 151 ++++ .../code_access_create.sol | 27 + .../code_access_create_standard_input.json | 46 ++ .../code_access_padding.sol | 18 + .../code_access_padding_standard_input.json | 154 ++++ .../code_access_runtime.sol | 27 + .../code_access_runtime_standard_input.json | 217 ++++++ .../various_code_length/code_length.sol | 64 ++ .../code_length_standard_input.json | 130 ++++ .../code_length_contract_member.sol | 15 + ...length_contract_member_standard_input.json | 145 ++++ .../codebalance_assembly.sol | 27 + .../codebalance_assembly_standard_input.json | 37 + .../various_codehash/codehash.sol | 19 + .../codehash_standard_input.json | 94 +++ .../codehash_assembly.sol | 23 + .../codehash_assembly_standard_input.json | 82 ++ .../contract_binary_dependencies.sol | 20 + ...ct_binary_dependencies_standard_input.json | 100 +++ .../crazy_elementary_typenames_on_stack.sol | 12 + ...ary_typenames_on_stack_standard_input.json | 43 ++ .../create_calldata.sol | 17 + .../create_calldata_standard_input.json | 142 ++++ .../various_create_random/create_random.sol | 39 + .../create_random_standard_input.json | 163 ++++ .../cross_contract_types.sol | 16 + .../cross_contract_types_standard_input.json | 136 ++++ .../various_decayed_tuple/decayed_tuple.sol | 9 + .../decayed_tuple_standard_input.json | 118 +++ .../destructuring_assignment.sol | 38 + ...structuring_assignment_standard_input.json | 76 ++ .../different_call_type_transient.sol | 51 ++ ...nt_call_type_transient_standard_input.json | 106 +++ .../empty_name_return_parameter.sol | 7 + ..._name_return_parameter_standard_input.json | 235 ++++++ .../semanticTests/various_erc20/erc20.sol | 131 ++++ .../various_erc20/erc20_standard_input.json | 52 ++ .../external_types_in_calls.sol | 29 + ...xternal_types_in_calls_standard_input.json | 79 ++ .../flipping_sign_tests.sol | 9 + .../flipping_sign_tests_standard_input.json | 103 +++ .../gasleft_decrease.sol | 19 + .../gasleft_decrease_standard_input.json | 193 +++++ .../gasleft_shadow_resolution.sol | 11 + ...left_shadow_resolution_standard_input.json | 91 +++ .../inline_member_init.sol | 18 + .../inline_member_init_standard_input.json | 70 ++ .../inline_member_init_inheritence.sol | 23 + ...ember_init_inheritence_standard_input.json | 208 +++++ .../inline_tuple_with_rational_numbers.sol | 8 + ..._with_rational_numbers_standard_input.json | 220 ++++++ .../iszero_bnot_correct.sol | 18 + .../iszero_bnot_correct_standard_input.json | 202 +++++ .../literal_empty_string.sol | 19 + .../literal_empty_string_standard_input.json | 241 ++++++ .../many_subassemblies.sol | 38 + .../many_subassemblies_standard_input.json | 172 +++++ .../memory_overwrite.sol | 9 + .../memory_overwrite_standard_input.json | 133 ++++ .../multi_modifiers.sol | 23 + .../multi_modifiers_standard_input.json | 139 ++++ .../multi_variable_declaration.sol | 46 ++ ...i_variable_declaration_standard_input.json | 40 + .../negative_stack_height.sol | 71 ++ .../negative_stack_height_standard_input.json | 166 ++++ .../nested_calldata_struct.sol | 25 + ...nested_calldata_struct_standard_input.json | 58 ++ .../nested_calldata_struct_to_memory.sol | 26 + ...ldata_struct_to_memory_standard_input.json | 196 +++++ .../positive_integers_to_signed.sol | 9 + ...ive_integers_to_signed_standard_input.json | 190 +++++ .../selfdestruct_post_cancun.sol | 91 +++ ...lfdestruct_post_cancun_standard_input.json | 169 ++++ ...uct_post_cancun_multiple_beneficiaries.sol | 70 ++ ...multiple_beneficiaries_standard_input.json | 178 +++++ .../selfdestruct_post_cancun_redeploy.sol | 111 +++ ...t_post_cancun_redeploy_standard_input.json | 184 +++++ .../selfdestruct_pre_cancun.sol | 89 +++ ...elfdestruct_pre_cancun_standard_input.json | 205 +++++ ...ruct_pre_cancun_multiple_beneficiaries.sol | 74 ++ ...multiple_beneficiaries_standard_input.json | 73 ++ .../selfdestruct_pre_cancun_redeploy.sol | 106 +++ ...ct_pre_cancun_redeploy_standard_input.json | 121 +++ .../senders_balance.sol | 25 + .../senders_balance_standard_input.json | 34 + .../single_copy_with_multiple_inheritance.sol | 32 + ...h_multiple_inheritance_standard_input.json | 148 ++++ .../skip_dynamic_types.sol | 14 + .../skip_dynamic_types_standard_input.json | 88 +++ ...or_static_arrays_with_dynamic_elements.sol | 23 + ..._with_dynamic_elements_standard_input.json | 232 ++++++ .../skip_dynamic_types_for_structs.sol | 24 + ...amic_types_for_structs_standard_input.json | 127 +++ .../state_variable_local_variable_mixture.sol | 10 + ...local_variable_mixture_standard_input.json | 67 ++ .../state_variable_under_contract_name.sol | 9 + ...le_under_contract_name_standard_input.json | 109 +++ .../staticcall_for_view_and_pure.sol | 53 ++ ...call_for_view_and_pure_standard_input.json | 211 +++++ ...iccall_for_view_and_pure_pre_byzantium.sol | 39 + ...and_pure_pre_byzantium_standard_input.json | 85 ++ ...string_as_mapping_key_without_variable.sol | 10 + ...g_key_without_variable_standard_input.json | 229 ++++++ .../various_store_bytes/store_bytes.sol | 13 + .../store_bytes_standard_input.json | 64 ++ .../various_string_tuples/string_tuples.sol | 16 + .../string_tuples_standard_input.json | 49 ++ .../semanticTests/various_super/super.sol | 28 + .../various_super/super_standard_input.json | 115 +++ .../various_super_alone/super_alone.sol | 7 + .../super_alone_standard_input.json | 181 +++++ .../super_parentheses.sol | 28 + .../super_parentheses_standard_input.json | 175 +++++ .../swap_in_storage_overwrite.sol | 36 + ...p_in_storage_overwrite_standard_input.json | 61 ++ .../test_underscore_in_hex.sol | 10 + ...test_underscore_in_hex_standard_input.json | 124 +++ .../transient_storage_reentrancy_lock.sol | 23 + ...torage_reentrancy_lock_standard_input.json | 97 +++ .../semanticTests/various_tuples/tuples.sol | 29 + .../various_tuples/tuples_standard_input.json | 238 ++++++ .../typed_multi_variable_declaration.sol | 25 + ...i_variable_declaration_standard_input.json | 157 ++++ .../various_value_complex/value_complex.sol | 28 + .../value_complex_standard_input.json | 160 ++++ .../various_value_insane/value_insane.sol | 27 + .../value_insane_standard_input.json | 214 ++++++ .../write_storage_external.sol | 39 + ...write_storage_external_standard_input.json | 223 ++++++ .../semanticTests/viaYul_assert/assert.sol | 20 + .../viaYul_assert/assert_standard_input.json | 142 ++++ .../assert_and_require.sol | 17 + .../assert_and_require_standard_input.json | 205 +++++ .../assign_tuple_from_function_call.sol | 14 + ...ple_from_function_call_standard_input.json | 172 +++++ .../checked_arithmetic.sol | 65 ++ .../checked_arithmetic_standard_input.json | 37 + .../viaYul_cleanup_comparison/comparison.sol | 39 + .../comparison_standard_input.json | 34 + .../viaYul_comparison/comparison.sol | 72 ++ .../comparison_standard_input.json | 88 +++ .../comparison_functions.sol | 29 + .../comparison_functions_standard_input.json | 190 +++++ .../conditional_multiple.sol | 8 + .../conditional_multiple_standard_input.json | 46 ++ .../conditional_true_false_literal.sol | 9 + ...nal_true_false_literal_standard_input.json | 40 + .../conditional_tuple.sol | 9 + .../conditional_tuple_standard_input.json | 37 + .../conditional_with_assignment.sol | 11 + ...tional_with_assignment_standard_input.json | 34 + .../conditional_with_variables.sol | 11 + ...itional_with_variables_standard_input.json | 43 ++ .../explicit_cast_assignment.sol | 8 + ...plicit_cast_assignment_standard_input.json | 37 + .../explicit_cast_function_call.sol | 10 + ...cit_cast_function_call_standard_input.json | 43 ++ .../explicit_cast_local_assignment.sol | 8 + ..._cast_local_assignment_standard_input.json | 52 ++ .../explicit_string_bytes_calldata_cast.sol | 9 + ...ng_bytes_calldata_cast_standard_input.json | 46 ++ .../function_cast.sol | 21 + .../function_cast_standard_input.json | 34 + .../implicit_cast_assignment.sol | 12 + ...plicit_cast_assignment_standard_input.json | 55 ++ .../implicit_cast_function_call.sol | 15 + ...cit_cast_function_call_standard_input.json | 49 ++ .../implicit_cast_local_assignment.sol | 11 + ..._cast_local_assignment_standard_input.json | 40 + .../copy_struct_invalid_ir_bug.sol | 26 + ..._struct_invalid_ir_bug_standard_input.json | 43 ++ .../define_tuple_from_function_call.sol | 16 + ...ple_from_function_call_standard_input.json | 208 +++++ .../semanticTests/viaYul_delete/delete.sol | 23 + .../viaYul_delete/delete_standard_input.json | 139 ++++ .../detect_add_overflow.sol | 16 + .../detect_add_overflow_standard_input.json | 115 +++ .../detect_add_overflow_signed.sol | 37 + ...ct_add_overflow_signed_standard_input.json | 37 + .../detect_div_overflow.sol | 25 + .../detect_div_overflow_standard_input.json | 58 ++ .../detect_mod_zero.sol | 23 + .../detect_mod_zero_standard_input.json | 157 ++++ .../detect_mod_zero_signed.sol | 35 + ...detect_mod_zero_signed_standard_input.json | 112 +++ .../detect_mul_overflow.sol | 35 + .../detect_mul_overflow_standard_input.json | 160 ++++ .../detect_mul_overflow_signed.sol | 82 ++ ...ct_mul_overflow_signed_standard_input.json | 61 ++ .../detect_sub_overflow.sol | 15 + .../detect_sub_overflow_standard_input.json | 127 +++ .../detect_sub_overflow_signed.sol | 40 + ...ct_sub_overflow_signed_standard_input.json | 175 +++++ .../dirty_calldata_struct.sol | 18 + .../dirty_calldata_struct_standard_input.json | 49 ++ .../dirty_memory_dynamic_array.sol | 18 + ...y_memory_dynamic_array_standard_input.json | 55 ++ .../dirty_memory_int32.sol | 18 + .../dirty_memory_int32_standard_input.json | 199 +++++ .../dirty_memory_static_array.sol | 18 + ...ty_memory_static_array_standard_input.json | 193 +++++ .../dirty_memory_struct.sol | 22 + .../dirty_memory_struct_standard_input.json | 97 +++ .../dirty_memory_uint32.sol | 18 + .../dirty_memory_uint32_standard_input.json | 109 +++ ...y_return_corrupted_free_memory_pointer.sol | 7 + ...ed_free_memory_pointer_standard_input.json | 82 ++ .../test/semanticTests/viaYul_exp/exp.sol | 17 + .../viaYul_exp/exp_standard_input.json | 169 ++++ .../viaYul_exp_literals/exp_literals.sol | 49 ++ .../exp_literals_standard_input.json | 166 ++++ .../exp_literals_success.sol | 39 + .../exp_literals_success_standard_input.json | 46 ++ .../semanticTests/viaYul_exp_neg/exp_neg.sol | 31 + .../exp_neg_standard_input.json | 223 ++++++ .../exp_neg_overflow.sol | 36 + .../exp_neg_overflow_standard_input.json | 184 +++++ .../viaYul_exp_overflow/exp_overflow.sol | 29 + .../exp_overflow_standard_input.json | 202 +++++ .../viaYul_exp_various/exp_various.sol | 48 ++ .../exp_various_standard_input.json | 118 +++ .../function_address.sol | 15 + .../function_address_standard_input.json | 145 ++++ .../function_entry_checks.sol | 28 + .../function_entry_checks_standard_input.json | 40 + .../function_pointers.sol | 23 + .../function_pointers_standard_input.json | 103 +++ .../function_selector.sol | 11 + .../function_selector_standard_input.json | 130 ++++ examples/test/semanticTests/viaYul_if/if.sol | 80 ++ .../viaYul_if/if_standard_input.json | 151 ++++ .../semanticTests/viaYul_keccak/keccak.sol | 12 + .../viaYul_keccak/keccak_standard_input.json | 67 ++ .../local_address_assignment.sol | 8 + ...cal_address_assignment_standard_input.json | 187 +++++ .../local_assignment.sol | 8 + .../local_assignment_standard_input.json | 220 ++++++ .../local_bool_assignment.sol | 8 + .../local_bool_assignment_standard_input.json | 148 ++++ .../local_tuple_assignment.sol | 30 + ...local_tuple_assignment_standard_input.json | 214 ++++++ .../local_variable_without_init.sol | 8 + ..._variable_without_init_standard_input.json | 178 +++++ .../viaYul_loops_break/break.sol | 29 + .../break_standard_input.json | 43 ++ .../viaYul_loops_continue/continue.sol | 35 + .../continue_standard_input.json | 34 + .../viaYul_loops_return/return.sol | 32 + .../return_standard_input.json | 37 + .../viaYul_loops_simple/simple.sol | 37 + .../simple_standard_input.json | 40 + .../mapping_enum_key_getter.sol | 24 + ...apping_enum_key_getter_standard_input.json | 163 ++++ .../mapping_getters.sol | 38 + .../mapping_getters_standard_input.json | 124 +++ .../mapping_string_key.sol | 8 + .../mapping_string_key_standard_input.json | 85 ++ .../memory_struct_allow.sol | 19 + .../memory_struct_allow_standard_input.json | 73 ++ .../viaYul_msg_sender/msg_sender.sol | 9 + .../msg_sender_standard_input.json | 64 ++ .../viaYul_negation_bug/negation_bug.sol | 11 + .../negation_bug_standard_input.json | 70 ++ .../semanticTests/viaYul_require/require.sol | 43 ++ .../require_standard_input.json | 91 +++ .../semanticTests/viaYul_return/return.sol | 8 + .../viaYul_return/return_standard_input.json | 34 + .../return_and_convert.sol | 9 + .../return_and_convert_standard_input.json | 181 +++++ .../return_storage_pointers.sol | 14 + ...eturn_storage_pointers_standard_input.json | 196 +++++ .../viaYul_short_circuit/short_circuit.sol | 15 + .../short_circuit_standard_input.json | 154 ++++ .../simple_assignment.sol | 8 + .../simple_assignment_standard_input.json | 52 ++ .../simple_inline_asm.sol | 15 + .../simple_inline_asm_standard_input.json | 100 +++ .../viaYul_smoke_test/smoke_test.sol | 6 + .../smoke_test_standard_input.json | 121 +++ .../dirty_storage_bytes.sol | 16 + .../dirty_storage_bytes_standard_input.json | 40 + .../dirty_storage_bytes_long.sol | 18 + ...rty_storage_bytes_long_standard_input.json | 46 ++ .../dirty_storage_dynamic_array.sol | 18 + ..._storage_dynamic_array_standard_input.json | 37 + .../dirty_storage_static_array.sol | 16 + ...y_storage_static_array_standard_input.json | 55 ++ .../dirty_storage_struct.sol | 21 + .../dirty_storage_struct_standard_input.json | 49 ++ .../viaYul_storage_mappings/mappings.sol | 37 + .../mappings_standard_input.json | 52 ++ .../packed_storage.sol | 14 + .../packed_storage_standard_input.json | 34 + .../simple_storage.sol | 15 + .../simple_storage_standard_input.json | 43 ++ .../viaYul_string_format/string_format.sol | 11 + .../string_format_standard_input.json | 76 ++ .../string_literals.sol | 27 + .../string_literals_standard_input.json | 217 ++++++ .../struct_member_access.sol | 38 + .../struct_member_access_standard_input.json | 211 +++++ .../tuple_evaluation_order.sol | 12 + ...tuple_evaluation_order_standard_input.json | 106 +++ .../unary_fixedbytes.sol | 76 ++ .../unary_fixedbytes_standard_input.json | 136 ++++ .../unary_operations.sol | 136 ++++ .../unary_operations_standard_input.json | 133 ++++ .../various_inline_asm.sol | 21 + .../various_inline_asm_standard_input.json | 94 +++ .../virtual_functions.sol | 30 + .../virtual_functions_standard_input.json | 79 ++ .../internal_virtual_function_calls.sol | 18 + ...virtual_function_calls_standard_input.json | 40 + ...irtual_function_calls_through_dispatch.sol | 23 + ...calls_through_dispatch_standard_input.json | 34 + .../virtual_function_calls.sol | 19 + ...virtual_function_calls_standard_input.json | 43 ++ ...unction_usage_in_constructor_arguments.sol | 31 + ..._constructor_arguments_standard_input.json | 46 ++ ..._override_changing_mutability_internal.sol | 23 + ...ng_mutability_internal_standard_input.json | 49 ++ ...al_override_changing_mutability_public.sol | 23 + ...ging_mutability_public_standard_input.json | 37 + 3144 files changed, 177670 insertions(+) create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_enums/enums.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_enums/enums_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr.sol create mode 100644 examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_address/address.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_address/address_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_function/function.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_function/function_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_enums/enums.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_enums/enums_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation_standard_input.json create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct.sol create mode 100644 examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2.sol create mode 100644 examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_contract_array/contract_array.sol create mode 100644 examples/test/semanticTests/abiencodedecode_contract_array/contract_array_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2.sol create mode 100644 examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding.sol create mode 100644 examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2.sol create mode 100644 examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2_standard_input.json create mode 100644 examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3.sol create mode 100644 examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3_standard_input.json create mode 100644 examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable.sol create mode 100644 examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable_standard_input.json create mode 100644 examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable.sol create mode 100644 examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod.sol create mode 100644 examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero.sol create mode 100644 examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked.sol create mode 100644 examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_check_var_init/check_var_init.sol create mode 100644 examples/test/semanticTests/arithmetics_check_var_init/check_var_init_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1.sol create mode 100644 examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2.sol create mode 100644 examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked.sol create mode 100644 examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked.sol create mode 100644 examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero.sol create mode 100644 examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity.sol create mode 100644 examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_signed_mod/signed_mod.sol create mode 100644 examples/test/semanticTests/arithmetics_signed_mod/signed_mod_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked.sol create mode 100644 examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked_standard_input.json create mode 100644 examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero.sol create mode 100644 examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero_standard_input.json create mode 100644 examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment.sol create mode 100644 examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment_standard_input.json create mode 100644 examples/test/semanticTests/array_array_2d_new/array_2d_new.sol create mode 100644 examples/test/semanticTests/array_array_2d_new/array_2d_new_standard_input.json create mode 100644 examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment.sol create mode 100644 examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment_standard_input.json create mode 100644 examples/test/semanticTests/array_array_3d_new/array_3d_new.sol create mode 100644 examples/test/semanticTests/array_array_3d_new/array_3d_new_standard_input.json create mode 100644 examples/test/semanticTests/array_array_function_pointers/array_function_pointers.sol create mode 100644 examples/test/semanticTests/array_array_function_pointers/array_function_pointers_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static.sol create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter.sol create mode 100644 examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_create/array_memory_create.sol create mode 100644 examples/test/semanticTests/array_array_memory_create/array_memory_create_standard_input.json create mode 100644 examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference.sol create mode 100644 examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference_standard_input.json create mode 100644 examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg.sol create mode 100644 examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access.sol create mode 100644 examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test.sol create mode 100644 examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test.sol create mode 100644 examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access.sol create mode 100644 examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length.sol create mode 100644 examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty.sol create mode 100644 examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address.sol create mode 100644 examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address_standard_input.json create mode 100644 examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop.sol create mode 100644 examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop_standard_input.json create mode 100644 examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage.sol create mode 100644 examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout.sol create mode 100644 examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout_standard_input.json create mode 100644 examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2.sol create mode 100644 examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2_standard_input.json create mode 100644 examples/test/semanticTests/array_bytes_length_member/bytes_length_member.sol create mode 100644 examples/test/semanticTests/array_bytes_length_member/bytes_length_member_standard_input.json create mode 100644 examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup.sol create mode 100644 examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple.sol create mode 100644 examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple_standard_input.json create mode 100644 examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long.sol create mode 100644 examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array/calldata_array.sol create mode 100644 examples/test/semanticTests/array_calldata_array/calldata_array_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function.sol create mode 100644 examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol create mode 100644 examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle.sol create mode 100644 examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct.sol create mode 100644 examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional.sol create mode 100644 examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1.sol create mode 100644 examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol create mode 100644 examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json create mode 100644 examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access.sol create mode 100644 examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings_standard_input.json create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested.sol create mode 100644 examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested_standard_input.json create mode 100644 examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length.sol create mode 100644 examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2.sol create mode 100644 examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping.sol create mode 100644 examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot.sol create mode 100644 examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping.sol create mode 100644 examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata.sol create mode 100644 examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings.sol create mode 100644 examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base.sol create mode 100644 examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy.sol create mode 100644 examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array.sol create mode 100644 examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data.sol create mode 100644 examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign.sol create mode 100644 examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy.sol create mode 100644 examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir.sol create mode 100644 examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy.sol create mode 100644 examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base.sol create mode 100644 examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol create mode 100644 examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested.sol create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes.sol create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer.sol create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct.sol create mode 100644 examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed.sol create mode 100644 examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn.sol create mode 100644 examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn_standard_input.json create mode 100644 examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata.sol create mode 100644 examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata_standard_input.json create mode 100644 examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length.sol create mode 100644 examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length_standard_input.json create mode 100644 examples/test/semanticTests/array_create_memory_array/create_memory_array.sol create mode 100644 examples/test/semanticTests/array_create_memory_array/create_memory_array_standard_input.json create mode 100644 examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large.sol create mode 100644 examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large_standard_input.json create mode 100644 examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array.sol create mode 100644 examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array_standard_input.json create mode 100644 examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays.sol create mode 100644 examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element.sol create mode 100644 examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array.sol create mode 100644 examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array.sol create mode 100644 examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs.sol create mode 100644 examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data.sol create mode 100644 examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array.sol create mode 100644 examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed.sol create mode 100644 examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed_standard_input.json create mode 100644 examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete.sol create mode 100644 examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete_standard_input.json create mode 100644 examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup.sol create mode 100644 examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage.sol create mode 100644 examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup.sol create mode 100644 examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access.sol create mode 100644 examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access_standard_input.json create mode 100644 examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access.sol create mode 100644 examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access_standard_input.json create mode 100644 examples/test/semanticTests/array_external_array_args/external_array_args.sol create mode 100644 examples/test/semanticTests/array_external_array_args/external_array_args_standard_input.json create mode 100644 examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup.sol create mode 100644 examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type.sol create mode 100644 examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type_standard_input.json create mode 100644 examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors.sol create mode 100644 examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors_standard_input.json create mode 100644 examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage.sol create mode 100644 examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access.sol create mode 100644 examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access_standard_input.json create mode 100644 examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access.sol create mode 100644 examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access_standard_input.json create mode 100644 examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls.sol create mode 100644 examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls_standard_input.json create mode 100644 examples/test/semanticTests/array_function_memory_array/function_memory_array.sol create mode 100644 examples/test/semanticTests/array_function_memory_array/function_memory_array_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access.sol create mode 100644 examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory.sol create mode 100644 examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access.sol create mode 100644 examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access.sol create mode 100644 examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_index_access/index_access.sol create mode 100644 examples/test/semanticTests/array_indexAccess_index_access/index_access_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints.sol create mode 100644 examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings.sol create mode 100644 examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write.sol create mode 100644 examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write_standard_input.json create mode 100644 examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write.sol create mode 100644 examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write_standard_input.json create mode 100644 examples/test/semanticTests/array_inline_array_return/inline_array_return.sol create mode 100644 examples/test/semanticTests/array_inline_array_return/inline_array_return_standard_input.json create mode 100644 examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton.sol create mode 100644 examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton_standard_input.json create mode 100644 examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints.sol create mode 100644 examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints_standard_input.json create mode 100644 examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings.sol create mode 100644 examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings_standard_input.json create mode 100644 examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document.sol create mode 100644 examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document_standard_input.json create mode 100644 examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array.sol create mode 100644 examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array_standard_input.json create mode 100644 examples/test/semanticTests/array_memory/memory.sol create mode 100644 examples/test/semanticTests/array_memory/memory_standard_input.json create mode 100644 examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes.sol create mode 100644 examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop/array_pop.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop/array_pop_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition.sol create mode 100644 examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty.sol create mode 100644 examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty_standard_input.json create mode 100644 examples/test/semanticTests/array_pop_parenthesized/parenthesized.sol create mode 100644 examples/test/semanticTests/array_pop_parenthesized/parenthesized_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push/array_push.sol create mode 100644 examples/test/semanticTests/array_push_array_push/array_push_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push_nested/array_push_nested.sol create mode 100644 examples/test/semanticTests/array_push_array_push_nested/array_push_nested_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata.sol create mode 100644 examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory.sol create mode 100644 examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array.sol create mode 100644 examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push_struct/array_push_struct.sol create mode 100644 examples/test/semanticTests/array_push_array_push_struct/array_push_struct_standard_input.json create mode 100644 examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata.sol create mode 100644 examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata_standard_input.json create mode 100644 examples/test/semanticTests/array_push_byte_array_push/byte_array_push.sol create mode 100644 examples/test/semanticTests/array_push_byte_array_push/byte_array_push_standard_input.json create mode 100644 examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition.sol create mode 100644 examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition_standard_input.json create mode 100644 examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push.sol create mode 100644 examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push_standard_input.json create mode 100644 examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d.sol create mode 100644 examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d_standard_input.json create mode 100644 examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d.sol create mode 100644 examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d_standard_input.json create mode 100644 examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes.sol create mode 100644 examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes_standard_input.json create mode 100644 examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct.sol create mode 100644 examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct_standard_input.json create mode 100644 examples/test/semanticTests/array_reusing_memory/reusing_memory.sol create mode 100644 examples/test/semanticTests/array_reusing_memory/reusing_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup.sol create mode 100644 examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment.sol create mode 100644 examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment_standard_input.json create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls.sol create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls_standard_input.json create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata.sol create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata_standard_input.json create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/array_storage_array_ref/storage_array_ref.sol create mode 100644 examples/test/semanticTests/array_storage_array_ref/storage_array_ref_standard_input.json create mode 100644 examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug.sol create mode 100644 examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug_standard_input.json create mode 100644 examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion.sol create mode 100644 examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion_standard_input.json create mode 100644 examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes.sol create mode 100644 examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes_standard_input.json create mode 100644 examples/test/semanticTests/array_strings_in_struct/strings_in_struct.sol create mode 100644 examples/test/semanticTests/array_strings_in_struct/strings_in_struct_standard_input.json create mode 100644 examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break.sol create mode 100644 examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break_standard_input.json create mode 100644 examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue.sol create mode 100644 examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue_standard_input.json create mode 100644 examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested.sol create mode 100644 examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak.sol create mode 100644 examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_blobhash/blobhash.sol create mode 100644 examples/test/semanticTests/builtinFunctions_blobhash/blobhash_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution.sol create mode 100644 examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_blockhash/blockhash.sol create mode 100644 examples/test/semanticTests/builtinFunctions_blockhash/blockhash_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution.sol create mode 100644 examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig.sol create mode 100644 examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes.sol create mode 100644 examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256/keccak256.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256/keccak256_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes.sol create mode 100644 examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig.sol create mode 100644 examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same.sol create mode 100644 examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160.sol create mode 100644 examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty.sol create mode 100644 examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed.sol create mode 100644 examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_sha256/sha256.sol create mode 100644 examples/test/semanticTests/builtinFunctions_sha256/sha256_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty.sol create mode 100644 examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty_standard_input.json create mode 100644 examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed.sol create mode 100644 examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed_standard_input.json create mode 100644 examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup.sol create mode 100644 examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation.sol create mode 100644 examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access.sol create mode 100644 examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes.sol create mode 100644 examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access.sol create mode 100644 examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length.sol create mode 100644 examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional.sol create mode 100644 examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes.sol create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice.sol create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array.sol create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct.sol create mode 100644 examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external.sol create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal.sol create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory.sol create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode.sol create mode 100644 examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer.sol create mode 100644 examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library.sol create mode 100644 examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array.sol create mode 100644 examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array.sol create mode 100644 examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed.sol create mode 100644 examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array.sol create mode 100644 examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_struct/calldata_struct.sol create mode 100644 examples/test/semanticTests/calldata_calldata_struct/calldata_struct_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning.sol create mode 100644 examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning_standard_input.json create mode 100644 examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal.sol create mode 100644 examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal_standard_input.json create mode 100644 examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data.sol create mode 100644 examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1.sol create mode 100644 examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2.sol create mode 100644 examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign.sol create mode 100644 examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup.sol create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct.sol create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base.sol create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base.sol create mode 100644 examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast.sol create mode 100644 examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast_standard_input.json create mode 100644 examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions.sol create mode 100644 examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions_standard_input.json create mode 100644 examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod.sol create mode 100644 examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod_standard_input.json create mode 100644 examples/test/semanticTests/constantEvaluator_rounding/rounding.sol create mode 100644 examples/test/semanticTests/constantEvaluator_rounding/rounding_standard_input.json create mode 100644 examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression.sol create mode 100644 examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression_standard_input.json create mode 100644 examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level.sol create mode 100644 examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level_standard_input.json create mode 100644 examples/test/semanticTests/constants_constant_string/constant_string.sol create mode 100644 examples/test/semanticTests/constants_constant_string/constant_string_standard_input.json create mode 100644 examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level.sol create mode 100644 examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level_standard_input.json create mode 100644 examples/test/semanticTests/constants_constant_variables/constant_variables.sol create mode 100644 examples/test/semanticTests/constants_constant_variables/constant_variables_standard_input.json create mode 100644 examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing.sol create mode 100644 examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing_standard_input.json create mode 100644 examples/test/semanticTests/constants_consteval_array_length/consteval_array_length.sol create mode 100644 examples/test/semanticTests/constants_consteval_array_length/consteval_array_length_standard_input.json create mode 100644 examples/test/semanticTests/constants_function_unreferenced/function_unreferenced.sol create mode 100644 examples/test/semanticTests/constants_function_unreferenced/function_unreferenced_standard_input.json create mode 100644 examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files.sol create mode 100644 examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files_standard_input.json create mode 100644 examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test.sol create mode 100644 examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test_standard_input.json create mode 100644 examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors.sol create mode 100644 examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors_standard_input.json create mode 100644 examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments.sol create mode 100644 examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments_standard_input.json create mode 100644 examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer.sol create mode 100644 examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer_standard_input.json create mode 100644 examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker.sol create mode 100644 examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker_standard_input.json create mode 100644 examples/test/semanticTests/constructor_callvalue_check/callvalue_check.sol create mode 100644 examples/test/semanticTests/constructor_callvalue_check/callvalue_check_standard_input.json create mode 100644 examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external.sol create mode 100644 examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external_standard_input.json create mode 100644 examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal.sol create mode 100644 examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal_standard_input.json create mode 100644 examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument.sol create mode 100644 examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument_standard_input.json create mode 100644 examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex.sol create mode 100644 examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex_standard_input.json create mode 100644 examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument.sol create mode 100644 examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument_standard_input.json create mode 100644 examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail.sol create mode 100644 examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail_standard_input.json create mode 100644 examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments.sol create mode 100644 examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments_standard_input.json create mode 100644 examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor.sol create mode 100644 examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor_standard_input.json create mode 100644 examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch.sol create mode 100644 examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch_standard_input.json create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order.sol create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order_standard_input.json create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2.sol create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2_standard_input.json create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy.sol create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy_standard_input.json create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR.sol create mode 100644 examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR_standard_input.json create mode 100644 examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor.sol create mode 100644 examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor_standard_input.json create mode 100644 examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check.sol create mode 100644 examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check_standard_input.json create mode 100644 examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation.sol create mode 100644 examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation_standard_input.json create mode 100644 examples/test/semanticTests/constructor_payable_constructor/payable_constructor.sol create mode 100644 examples/test/semanticTests/constructor_payable_constructor/payable_constructor_standard_input.json create mode 100644 examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor.sol create mode 100644 examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor_standard_input.json create mode 100644 examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed.sol create mode 100644 examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed_standard_input.json create mode 100644 examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor.sol create mode 100644 examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor_standard_input.json create mode 100644 examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor.sol create mode 100644 examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor_standard_input.json create mode 100644 examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization.sol create mode 100644 examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization_standard_input.json create mode 100644 examples/test/semanticTests/constructor_with_params_1/constructor_with_params.sol create mode 100644 examples/test/semanticTests/constructor_with_params_1/constructor_with_params_standard_input.json create mode 100644 examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance.sol create mode 100644 examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance_standard_input.json create mode 100644 examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance.sol create mode 100644 examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance_standard_input.json create mode 100644 examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2.sol create mode 100644 examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2_standard_input.json create mode 100644 examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage.sol create mode 100644 examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes.sol create mode 100644 examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_library_function/library_function.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_library_function/library_function_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_module_function/module_function.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_module_function/module_function_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_super_function/super_function.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_super_function/super_function_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function_standard_input.json create mode 100644 examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed.sol create mode 100644 examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed_standard_input.json create mode 100644 examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes.sol create mode 100644 examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes_standard_input.json create mode 100644 examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array.sol create mode 100644 examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/ecrecover_ecrecover/ecrecover.sol create mode 100644 examples/test/semanticTests/ecrecover_ecrecover/ecrecover_standard_input.json create mode 100644 examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2.sol create mode 100644 examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2_standard_input.json create mode 100644 examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input.sol create mode 100644 examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input_standard_input.json create mode 100644 examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm.sol create mode 100644 examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm_standard_input.json create mode 100644 examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper.sol create mode 100644 examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper_standard_input.json create mode 100644 examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events.sol create mode 100644 examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events_standard_input.json create mode 100644 examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events.sol create mode 100644 examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events_standard_input.json create mode 100644 examples/test/semanticTests/empty_contract_1/empty_contract.sol create mode 100644 examples/test/semanticTests/empty_contract_1/empty_contract_standard_input.json create mode 100644 examples/test/semanticTests/empty_for_loop_1/empty_for_loop.sol create mode 100644 examples/test/semanticTests/empty_for_loop_1/empty_for_loop_standard_input.json create mode 100644 examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints.sol create mode 100644 examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints_standard_input.json create mode 100644 examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow.sol create mode 100644 examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow_standard_input.json create mode 100644 examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead.sol create mode 100644 examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead_standard_input.json create mode 100644 examples/test/semanticTests/enums_enum_referencing/enum_referencing.sol create mode 100644 examples/test/semanticTests/enums_enum_referencing/enum_referencing_standard_input.json create mode 100644 examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members.sol create mode 100644 examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members_standard_input.json create mode 100644 examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged.sol create mode 100644 examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged_standard_input.json create mode 100644 examples/test/semanticTests/enums_minmax/minmax.sol create mode 100644 examples/test/semanticTests/enums_minmax/minmax_standard_input.json create mode 100644 examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name.sol create mode 100644 examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name_standard_input.json create mode 100644 examples/test/semanticTests/enums_using_enums/using_enums.sol create mode 100644 examples/test/semanticTests/enums_using_enums/using_enums_standard_input.json create mode 100644 examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum.sol create mode 100644 examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum_standard_input.json create mode 100644 examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly.sol create mode 100644 examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly_standard_input.json create mode 100644 examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface.sol create mode 100644 examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface_standard_input.json create mode 100644 examples/test/semanticTests/errors_error_selector/error_selector.sol create mode 100644 examples/test/semanticTests/errors_error_selector/error_selector_standard_input.json create mode 100644 examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array.sol create mode 100644 examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type.sol create mode 100644 examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type_standard_input.json create mode 100644 examples/test/semanticTests/errors_named_error_args/named_error_args.sol create mode 100644 examples/test/semanticTests/errors_named_error_args/named_error_args_standard_input.json create mode 100644 examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types.sol create mode 100644 examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types_standard_input.json create mode 100644 examples/test/semanticTests/errors_panic_via_import/panic_via_import.sol create mode 100644 examples/test/semanticTests/errors_panic_via_import/panic_via_import_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters.sol create mode 100644 examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once.sol create mode 100644 examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1.sol create mode 100644 examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2.sol create mode 100644 examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3.sol create mode 100644 examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow.sol create mode 100644 examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter.sol create mode 100644 examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments.sol create mode 100644 examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check.sol create mode 100644 examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal.sol create mode 100644 examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory.sol create mode 100644 examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_error_uint256/require_error_uint256.sol create mode 100644 examples/test/semanticTests/errors_require_error_uint256/require_error_uint256_standard_input.json create mode 100644 examples/test/semanticTests/errors_require_inherited_error/require_inherited_error.sol create mode 100644 examples/test/semanticTests/errors_require_inherited_error/require_inherited_error_standard_input.json create mode 100644 examples/test/semanticTests/errors_revert_conversion/revert_conversion.sol create mode 100644 examples/test/semanticTests/errors_revert_conversion/revert_conversion_standard_input.json create mode 100644 examples/test/semanticTests/errors_simple/simple.sol create mode 100644 examples/test/semanticTests/errors_simple/simple_standard_input.json create mode 100644 examples/test/semanticTests/errors_small_error_optimization/small_error_optimization.sol create mode 100644 examples/test/semanticTests/errors_small_error_optimization/small_error_optimization_standard_input.json create mode 100644 examples/test/semanticTests/errors_using_structs/using_structs.sol create mode 100644 examples/test/semanticTests/errors_using_structs/using_structs_standard_input.json create mode 100644 examples/test/semanticTests/errors_via_contract_type/via_contract_type.sol create mode 100644 examples/test/semanticTests/errors_via_contract_type/via_contract_type_standard_input.json create mode 100644 examples/test/semanticTests/errors_via_import/via_import.sol create mode 100644 examples/test/semanticTests/errors_via_import/via_import_standard_input.json create mode 100644 examples/test/semanticTests/errors_weird_name/weird_name.sol create mode 100644 examples/test/semanticTests/errors_weird_name/weird_name_standard_input.json create mode 100644 examples/test/semanticTests/events_event/event.sol create mode 100644 examples/test/semanticTests/events_event/event_standard_input.json create mode 100644 examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit.sol create mode 100644 examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit_standard_input.json create mode 100644 examples/test/semanticTests/events_event_anonymous/event_anonymous.sol create mode 100644 examples/test/semanticTests/events_event_anonymous/event_anonymous_standard_input.json create mode 100644 examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision.sol create mode 100644 examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision_standard_input.json create mode 100644 examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2.sol create mode 100644 examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics.sol create mode 100644 examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics_standard_input.json create mode 100644 examples/test/semanticTests/events_event_constructor/event_constructor.sol create mode 100644 examples/test/semanticTests/events_event_constructor/event_constructor_standard_input.json create mode 100644 examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory.sol create mode 100644 examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory_standard_input.json create mode 100644 examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2.sol create mode 100644 examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage.sol create mode 100644 examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage_standard_input.json create mode 100644 examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2.sol create mode 100644 examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2.sol create mode 100644 examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2.sol create mode 100644 examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit/event_emit.sol create mode 100644 examples/test/semanticTests/events_event_emit/event_emit_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level.sol create mode 100644 examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract.sol create mode 100644 examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name.sol create mode 100644 examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract.sol create mode 100644 examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library.sol create mode 100644 examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library_standard_input.json create mode 100644 examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface.sol create mode 100644 examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface_standard_input.json create mode 100644 examples/test/semanticTests/events_event_indexed_function/event_indexed_function.sol create mode 100644 examples/test/semanticTests/events_event_indexed_function/event_indexed_function_standard_input.json create mode 100644 examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2.sol create mode 100644 examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed.sol create mode 100644 examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed_standard_input.json create mode 100644 examples/test/semanticTests/events_event_indexed_string/event_indexed_string.sol create mode 100644 examples/test/semanticTests/events_event_indexed_string/event_indexed_string_standard_input.json create mode 100644 examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data.sol create mode 100644 examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data_standard_input.json create mode 100644 examples/test/semanticTests/events_event_no_arguments/event_no_arguments.sol create mode 100644 examples/test/semanticTests/events_event_no_arguments/event_no_arguments_standard_input.json create mode 100644 examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data.sol create mode 100644 examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data_standard_input.json create mode 100644 examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage.sol create mode 100644 examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage_standard_input.json create mode 100644 examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage.sol create mode 100644 examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage_standard_input.json create mode 100644 examples/test/semanticTests/events_event_selector/event_selector.sol create mode 100644 examples/test/semanticTests/events_event_selector/event_selector_standard_input.json create mode 100644 examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level.sol create mode 100644 examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level_standard_input.json create mode 100644 examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level.sol create mode 100644 examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level_standard_input.json create mode 100644 examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library.sol create mode 100644 examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library_standard_input.json create mode 100644 examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array.sol create mode 100644 examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/events_event_string/event_string.sol create mode 100644 examples/test/semanticTests/events_event_string/event_string_standard_input.json create mode 100644 examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2.sol create mode 100644 examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2_standard_input.json create mode 100644 examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2.sol create mode 100644 examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2_standard_input.json create mode 100644 examples/test/semanticTests/events_events_with_same_name/events_with_same_name.sol create mode 100644 examples/test/semanticTests/events_events_with_same_name/events_with_same_name_standard_input.json create mode 100644 examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level.sol create mode 100644 examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level_standard_input.json create mode 100644 examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit.sol create mode 100644 examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit_standard_input.json create mode 100644 examples/test/semanticTests/events_simple/simple.sol create mode 100644 examples/test/semanticTests/events_simple/simple_standard_input.json create mode 100644 examples/test/semanticTests/experimental_stub/stub.sol create mode 100644 examples/test/semanticTests/experimental_stub/stub_standard_input.json create mode 100644 examples/test/semanticTests/experimental_type_class/type_class.sol create mode 100644 examples/test/semanticTests/experimental_type_class/type_class_standard_input.json create mode 100644 examples/test/semanticTests/exponentiation_literal_base/literal_base.sol create mode 100644 examples/test/semanticTests/exponentiation_literal_base/literal_base_standard_input.json create mode 100644 examples/test/semanticTests/exponentiation_signed_base/signed_base.sol create mode 100644 examples/test/semanticTests/exponentiation_signed_base/signed_base_standard_input.json create mode 100644 examples/test/semanticTests/exponentiation_small_exp/small_exp.sol create mode 100644 examples/test/semanticTests/exponentiation_small_exp/small_exp_standard_input.json create mode 100644 examples/test/semanticTests/expressions_bit_operators/bit_operators.sol create mode 100644 examples/test/semanticTests/expressions_bit_operators/bit_operators_standard_input.json create mode 100644 examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison.sol create mode 100644 examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples_standard_input.json create mode 100644 examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values.sol create mode 100644 examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values_standard_input.json create mode 100644 examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const.sol create mode 100644 examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const_standard_input.json create mode 100644 examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed.sol create mode 100644 examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed_standard_input.json create mode 100644 examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal.sol create mode 100644 examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal_standard_input.json create mode 100644 examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators.sol create mode 100644 examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators_standard_input.json create mode 100644 examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression.sol create mode 100644 examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression_standard_input.json create mode 100644 examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression.sol create mode 100644 examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression_standard_input.json create mode 100644 examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal.sol create mode 100644 examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal_standard_input.json create mode 100644 examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send.sol create mode 100644 examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar.sol create mode 100644 examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm.sol create mode 100644 examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm.sol create mode 100644 examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon.sol create mode 100644 examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18.sol create mode 100644 examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18.sol create mode 100644 examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils.sol create mode 100644 examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_base64/base64.sol create mode 100644 examples/test/semanticTests/externalContracts_base64/base64_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract.sol create mode 100644 examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed.sol create mode 100644 examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned.sol create mode 100644 examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi.sol create mode 100644 examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_snark/snark.sol create mode 100644 examples/test/semanticTests/externalContracts_snark/snark_standard_input.json create mode 100644 examples/test/semanticTests/externalContracts_strings/strings.sol create mode 100644 examples/test/semanticTests/externalContracts_strings/strings_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__external_external/external.sol create mode 100644 examples/test/semanticTests/externalSource__external_external/external_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__external_import/import.sol create mode 100644 examples/test/semanticTests/externalSource__external_import/import_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir.sol create mode 100644 examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__external_other_external/other_external.sol create mode 100644 examples/test/semanticTests/externalSource__external_other_external/other_external_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__external_subdir_import/import.sol create mode 100644 examples/test/semanticTests/externalSource__external_subdir_import/import_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external.sol create mode 100644 examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__non_normalized_paths_a/a.sol create mode 100644 examples/test/semanticTests/externalSource__non_normalized_paths_a/a_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__non_normalized_paths_c/c.sol create mode 100644 examples/test/semanticTests/externalSource__non_normalized_paths_c/c_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__non_normalized_paths_d/d.sol create mode 100644 examples/test/semanticTests/externalSource__non_normalized_paths_d/d_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_D_d/d.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_D_d/d_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_c/c.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_c/c_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_a/a.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_a/a_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__relative_imports_h/h.sol create mode 100644 examples/test/semanticTests/externalSource__relative_imports_h/h_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b.sol create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a.sol create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract.sol create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a.sol create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a_standard_input.json create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b.sol create mode 100644 examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs.sol create mode 100644 examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source.sol create mode 100644 examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_multisource/multisource.sol create mode 100644 examples/test/semanticTests/externalSource_multisource/multisource_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths.sol create mode 100644 examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_relative_imports/relative_imports.sol create mode 100644 examples/test/semanticTests/externalSource_relative_imports/relative_imports_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_source/source.sol create mode 100644 examples/test/semanticTests/externalSource_source/source_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_source_import/source_import.sol create mode 100644 examples/test/semanticTests/externalSource_source_import/source_import_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir.sol create mode 100644 examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots.sol create mode 100644 examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots_standard_input.json create mode 100644 examples/test/semanticTests/externalSource_source_remapping/source_remapping.sol create mode 100644 examples/test/semanticTests/externalSource_source_remapping/source_remapping_standard_input.json create mode 100644 examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes.sol create mode 100644 examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes_standard_input.json create mode 100644 examples/test/semanticTests/fallback_falback_return/falback_return.sol create mode 100644 examples/test/semanticTests/fallback_falback_return/falback_return_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_argument/fallback_argument.sol create mode 100644 examples/test/semanticTests/fallback_fallback_argument/fallback_argument_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage.sol create mode 100644 examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive.sol create mode 100644 examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_override/fallback_override.sol create mode 100644 examples/test/semanticTests/fallback_fallback_override/fallback_override_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_override2/fallback_override2.sol create mode 100644 examples/test/semanticTests/fallback_fallback_override2/fallback_override2_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi.sol create mode 100644 examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi_standard_input.json create mode 100644 examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data.sol create mode 100644 examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data_standard_input.json create mode 100644 examples/test/semanticTests/fallback_inherited/inherited.sol create mode 100644 examples/test/semanticTests/fallback_inherited/inherited_standard_input.json create mode 100644 examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback.sol create mode 100644 examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_easy/easy.sol create mode 100644 examples/test/semanticTests/freeFunctions_easy/easy_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function.sol create mode 100644 examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode.sol create mode 100644 examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_import/import.sol create mode 100644 examples/test/semanticTests/freeFunctions_import/import_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free.sol create mode 100644 examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_new_operator/new_operator.sol create mode 100644 examples/test/semanticTests/freeFunctions_new_operator/new_operator_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_overloads/overloads.sol create mode 100644 examples/test/semanticTests/freeFunctions_overloads/overloads_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_recursion/recursion.sol create mode 100644 examples/test/semanticTests/freeFunctions_recursion/recursion_standard_input.json create mode 100644 examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs.sol create mode 100644 examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars.sol create mode 100644 examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy.sol create mode 100644 examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function.sol create mode 100644 examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable.sol create mode 100644 examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string.sol create mode 100644 examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function.sol create mode 100644 examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer.sol create mode 100644 examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression.sol create mode 100644 examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer.sol create mode 100644 examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_call_options_overload/call_options_overload.sol create mode 100644 examples/test/semanticTests/functionCall_call_options_overload/call_options_overload_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws.sol create mode 100644 examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions.sol create mode 100644 examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function.sol create mode 100644 examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail.sol create mode 100644 examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array.sol create mode 100644 examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments.sol create mode 100644 examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args.sol create mode 100644 examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args.sol create mode 100644 examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt.sol create mode 100644 examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value.sol create mode 100644 examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium.sol create mode 100644 examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args.sol create mode 100644 examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_call/external_call.sol create mode 100644 examples/test/semanticTests/functionCall_external_call/external_call_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time.sol create mode 100644 examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata.sol create mode 100644 examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting.sol create mode 100644 examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings.sol create mode 100644 examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_call_value/external_call_value.sol create mode 100644 examples/test/semanticTests/functionCall_external_call_value/external_call_value_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_function/external_function.sol create mode 100644 examples/test/semanticTests/functionCall_external_function/external_function_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_external_public_override/external_public_override.sol create mode 100644 examples/test/semanticTests/functionCall_external_public_override/external_public_override_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_failed_create/failed_create.sol create mode 100644 examples/test/semanticTests/functionCall_failed_create/failed_create_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module.sol create mode 100644 examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic.sol create mode 100644 examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax.sol create mode 100644 examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base/call_base.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base/call_base_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface.sol create mode 100644 examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument.sol create mode 100644 examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument.sol create mode 100644 examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return.sol create mode 100644 examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_member_accessors/member_accessors.sol create mode 100644 examples/test/semanticTests/functionCall_member_accessors/member_accessors_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_multiple_functions/multiple_functions.sol create mode 100644 examples/test/semanticTests/functionCall_multiple_functions/multiple_functions_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values.sol create mode 100644 examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_named_args/named_args.sol create mode 100644 examples/test/semanticTests/functionCall_named_args/named_args_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_named_args_overload/named_args_overload.sol create mode 100644 examples/test/semanticTests/functionCall_named_args_overload/named_args_overload_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check.sol create mode 100644 examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected.sol create mode 100644 examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected.sol create mode 100644 examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead.sol create mode 100644 examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether.sol create mode 100644 examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_transaction_status/transaction_status.sol create mode 100644 examples/test/semanticTests/functionCall_transaction_status/transaction_status_standard_input.json create mode 100644 examples/test/semanticTests/functionCall_value_test/value_test.sol create mode 100644 examples/test/semanticTests/functionCall_value_test/value_test_standard_input.json create mode 100644 examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name.sol create mode 100644 examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_address_member/address_member.sol create mode 100644 examples/test/semanticTests/functionTypes_address_member/address_member_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir.sol create mode 100644 examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy.sol create mode 100644 examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits.sol create mode 100644 examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions.sol create mode 100644 examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher.sol create mode 100644 examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol create mode 100644 examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack.sol create mode 100644 examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage.sol create mode 100644 examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage.sol create mode 100644 examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal.sol create mode 100644 examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option.sol create mode 100644 examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions.sol create mode 100644 examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally.sol create mode 100644 examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally.sol create mode 100644 examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime.sol create mode 100644 examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check.sol create mode 100644 examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_selector_1/selector_1.sol create mode 100644 examples/test/semanticTests/functionTypes_selector_1/selector_1_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_selector_2/selector_2.sol create mode 100644 examples/test/semanticTests/functionTypes_selector_2/selector_2_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression.sol create mode 100644 examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect.sol create mode 100644 examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary.sol create mode 100644 examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call.sol create mode 100644 examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function.sol create mode 100644 examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_store_function/store_function.sol create mode 100644 examples/test/semanticTests/functionTypes_store_function/store_function_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function.sol create mode 100644 examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions.sol create mode 100644 examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function.sol create mode 100644 examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function.sol create mode 100644 examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function.sol create mode 100644 examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function_standard_input.json create mode 100644 examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call.sol create mode 100644 examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call_standard_input.json create mode 100644 examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct.sol create mode 100644 examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct_standard_input.json create mode 100644 examples/test/semanticTests/getters_arrays/arrays.sol create mode 100644 examples/test/semanticTests/getters_arrays/arrays_standard_input.json create mode 100644 examples/test/semanticTests/getters_bytes/bytes.sol create mode 100644 examples/test/semanticTests/getters_bytes/bytes_standard_input.json create mode 100644 examples/test/semanticTests/getters_mapping/mapping.sol create mode 100644 examples/test/semanticTests/getters_mapping/mapping_standard_input.json create mode 100644 examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct.sol create mode 100644 examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct_standard_input.json create mode 100644 examples/test/semanticTests/getters_mapping_of_string/mapping_of_string.sol create mode 100644 examples/test/semanticTests/getters_mapping_of_string/mapping_of_string_standard_input.json create mode 100644 examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct.sol create mode 100644 examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct_standard_input.json create mode 100644 examples/test/semanticTests/getters_mapping_with_names/mapping_with_names.sol create mode 100644 examples/test/semanticTests/getters_mapping_with_names/mapping_with_names_standard_input.json create mode 100644 examples/test/semanticTests/getters_string_and_bytes/string_and_bytes.sol create mode 100644 examples/test/semanticTests/getters_string_and_bytes/string_and_bytes_standard_input.json create mode 100644 examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes.sol create mode 100644 examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes_standard_input.json create mode 100644 examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple.sol create mode 100644 examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple_standard_input.json create mode 100644 examples/test/semanticTests/getters_transient_value_types/transient_value_types.sol create mode 100644 examples/test/semanticTests/getters_transient_value_types/transient_value_types_standard_input.json create mode 100644 examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call.sol create mode 100644 examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call_standard_input.json create mode 100644 examples/test/semanticTests/getters_value_types/value_types.sol create mode 100644 examples/test/semanticTests/getters_value_types/value_types_standard_input.json create mode 100644 examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration.sol create mode 100644 examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration_standard_input.json create mode 100644 examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables.sol create mode 100644 examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables_standard_input.json create mode 100644 examples/test/semanticTests/immutable_delete/delete.sol create mode 100644 examples/test/semanticTests/immutable_delete/delete_standard_input.json create mode 100644 examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor.sol create mode 100644 examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor_standard_input.json create mode 100644 examples/test/semanticTests/immutable_getter/getter.sol create mode 100644 examples/test/semanticTests/immutable_getter/getter_standard_input.json create mode 100644 examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor.sol create mode 100644 examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor_standard_input.json create mode 100644 examples/test/semanticTests/immutable_immutable_signed/immutable_signed.sol create mode 100644 examples/test/semanticTests/immutable_immutable_signed/immutable_signed_standard_input.json create mode 100644 examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug.sol create mode 100644 examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug_standard_input.json create mode 100644 examples/test/semanticTests/immutable_increment_decrement/increment_decrement.sol create mode 100644 examples/test/semanticTests/immutable_increment_decrement/increment_decrement_standard_input.json create mode 100644 examples/test/semanticTests/immutable_inheritance/inheritance.sol create mode 100644 examples/test/semanticTests/immutable_inheritance/inheritance_standard_input.json create mode 100644 examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer.sol create mode 100644 examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer_standard_input.json create mode 100644 examples/test/semanticTests/immutable_multi_creation/multi_creation.sol create mode 100644 examples/test/semanticTests/immutable_multi_creation/multi_creation_standard_input.json create mode 100644 examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations.sol create mode 100644 examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations_standard_input.json create mode 100644 examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor.sol create mode 100644 examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor_standard_input.json create mode 100644 examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse.sol create mode 100644 examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse_standard_input.json create mode 100644 examples/test/semanticTests/immutable_stub/stub.sol create mode 100644 examples/test/semanticTests/immutable_stub/stub_standard_input.json create mode 100644 examples/test/semanticTests/immutable_uninitialized/uninitialized.sol create mode 100644 examples/test/semanticTests/immutable_uninitialized/uninitialized_standard_input.json create mode 100644 examples/test/semanticTests/immutable_use_scratch/use_scratch.sol create mode 100644 examples/test/semanticTests/immutable_use_scratch/use_scratch_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_access_base_storage/access_base_storage.sol create mode 100644 examples/test/semanticTests/inheritance_access_base_storage/access_base_storage_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution.sol create mode 100644 examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables.sol create mode 100644 examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata.sol create mode 100644 examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct.sol create mode 100644 examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect.sol create mode 100644 examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class.sol create mode 100644 examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_function/inherited_function.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_function/inherited_function_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch.sol create mode 100644 examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor.sol create mode 100644 examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first.sol create mode 100644 examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second.sol create mode 100644 examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else.sol create mode 100644 examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base.sol create mode 100644 examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base.sol create mode 100644 examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap.sol create mode 100644 examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor.sol create mode 100644 examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment.sol create mode 100644 examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_super_overload/super_overload.sol create mode 100644 examples/test/semanticTests/inheritance_super_overload/super_overload_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable.sol create mode 100644 examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract.sol create mode 100644 examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract_standard_input.json create mode 100644 examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor.sol create mode 100644 examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function.sol create mode 100644 examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function.sol create mode 100644 examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_blobhash/blobhash.sol create mode 100644 examples/test/semanticTests/inlineAssembly_blobhash/blobhash_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count.sol create mode 100644 examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun.sol create mode 100644 examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return.sol create mode 100644 examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_chainid/chainid.sol create mode 100644 examples/test/semanticTests/inlineAssembly_chainid/chainid_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_constant_access/constant_access.sol create mode 100644 examples/test/semanticTests/inlineAssembly_constant_access/constant_access_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing.sol create mode 100644 examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_difficulty/difficulty.sol create mode 100644 examples/test/semanticTests/inlineAssembly_difficulty/difficulty_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address.sol create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment.sol create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector.sol create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment.sol create mode 100644 examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing.sol create mode 100644 examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash.sol create mode 100644 examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let.sol create mode 100644 examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly.sol create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization.sol create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location.sol create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug.sol create mode 100644 examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string.sol create mode 100644 examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization.sol create mode 100644 examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_leave/leave.sol create mode 100644 examples/test/semanticTests/inlineAssembly_leave/leave_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy/mcopy.sol create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy/mcopy_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun.sol create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty.sol create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap.sol create mode 100644 examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block.sol create mode 100644 examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport.sol create mode 100644 examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao.sol create mode 100644 examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance.sol create mode 100644 examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode.sol create mode 100644 examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_slot_access/slot_access.sol create mode 100644 examples/test/semanticTests/inlineAssembly_slot_access/slot_access_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer.sol create mode 100644 examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun.sol create mode 100644 examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock.sol create mode 100644 examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_truefalse/truefalse.sol create mode 100644 examples/test/semanticTests/inlineAssembly_truefalse/truefalse_standard_input.json create mode 100644 examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall.sol create mode 100644 examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall_standard_input.json create mode 100644 examples/test/semanticTests/integer_basic/basic.sol create mode 100644 examples/test/semanticTests/integer_basic/basic_standard_input.json create mode 100644 examples/test/semanticTests/integer_int/int.sol create mode 100644 examples/test/semanticTests/integer_int/int_standard_input.json create mode 100644 examples/test/semanticTests/integer_many_local_variables/many_local_variables.sol create mode 100644 examples/test/semanticTests/integer_many_local_variables/many_local_variables_standard_input.json create mode 100644 examples/test/semanticTests/integer_small_signed_types/small_signed_types.sol create mode 100644 examples/test/semanticTests/integer_small_signed_types/small_signed_types_standard_input.json create mode 100644 examples/test/semanticTests/integer_uint/uint.sol create mode 100644 examples/test/semanticTests/integer_uint/uint_standard_input.json create mode 100644 examples/test/semanticTests/interfaceID_homer/homer.sol create mode 100644 examples/test/semanticTests/interfaceID_homer/homer_standard_input.json create mode 100644 examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId.sol create mode 100644 examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId_standard_input.json create mode 100644 examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events.sol create mode 100644 examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events_standard_input.json create mode 100644 examples/test/semanticTests/interfaceID_interfaces/interfaces.sol create mode 100644 examples/test/semanticTests/interfaceID_interfaces/interfaces_standard_input.json create mode 100644 examples/test/semanticTests/interfaceID_lisa/lisa.sol create mode 100644 examples/test/semanticTests/interfaceID_lisa/lisa_standard_input.json create mode 100644 examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId.sol create mode 100644 examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId_standard_input.json create mode 100644 examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions.sol create mode 100644 examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions_standard_input.json create mode 100644 examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting.sol create mode 100644 examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_account/account.sol create mode 100644 examples/test/semanticTests/isoltestTesting_account/account_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract.sol create mode 100644 examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance.sol create mode 100644 examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2.sol create mode 100644 examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance.sol create mode 100644 examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_builtins/builtins.sol create mode 100644 examples/test/semanticTests/isoltestTesting_builtins/builtins_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_effects/effects.sol create mode 100644 examples/test/semanticTests/isoltestTesting_effects/effects_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars.sol create mode 100644 examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty.sol create mode 100644 examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty_standard_input.json create mode 100644 examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty.sol create mode 100644 examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty_standard_input.json create mode 100644 examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata.sol create mode 100644 examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata_standard_input.json create mode 100644 examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata.sol create mode 100644 examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata_standard_input.json create mode 100644 examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata.sol.sol create mode 100644 examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata_standard_input.json create mode 100644 examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata.sol create mode 100644 examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata_standard_input.json create mode 100644 examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter.sol create mode 100644 examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter_standard_input.json create mode 100644 examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter.sol create mode 100644 examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter_standard_input.json create mode 100644 examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter.sol create mode 100644 examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses.sol create mode 100644 examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses.sol create mode 100644 examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function/internal_library_function.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function/internal_library_function_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size.sol create mode 100644 examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size_standard_input.json create mode 100644 examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library.sol create mode 100644 examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_address/library_address.sol create mode 100644 examples/test/semanticTests/libraries_library_address/library_address_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead.sol create mode 100644 examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module.sol create mode 100644 examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead.sol create mode 100644 examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure.sol create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed.sol create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed.sol create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall.sol create mode 100644 examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression.sol create mode 100644 examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors.sol create mode 100644 examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct.sol create mode 100644 examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve.sol create mode 100644 examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping.sol create mode 100644 examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall.sol create mode 100644 examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_stray_values/library_stray_values.sol create mode 100644 examples/test/semanticTests/libraries_library_stray_values/library_stray_values_standard_input.json create mode 100644 examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression.sol create mode 100644 examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression_standard_input.json create mode 100644 examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library.sol create mode 100644 examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library_standard_input.json create mode 100644 examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library.sol create mode 100644 examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library_standard_input.json create mode 100644 examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named.sol create mode 100644 examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named_standard_input.json create mode 100644 examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library.sol create mode 100644 examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library_standard_input.json create mode 100644 examples/test/semanticTests/libraries_stub/stub.sol create mode 100644 examples/test/semanticTests/libraries_stub/stub_standard_input.json create mode 100644 examples/test/semanticTests/libraries_stub_internal/stub_internal.sol create mode 100644 examples/test/semanticTests/libraries_stub_internal/stub_internal_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name.sol create mode 100644 examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int.sol create mode 100644 examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_for_overload/using_for_overload.sol create mode 100644 examples/test/semanticTests/libraries_using_for_overload/using_for_overload_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs.sol create mode 100644 examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public.sol create mode 100644 examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return.sol create mode 100644 examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return_standard_input.json create mode 100644 examples/test/semanticTests/libraries_using_library_structs/using_library_structs.sol create mode 100644 examples/test/semanticTests/libraries_using_library_structs/using_library_structs_standard_input.json create mode 100644 examples/test/semanticTests/literals_denominations/denominations.sol create mode 100644 examples/test/semanticTests/literals_denominations/denominations_standard_input.json create mode 100644 examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes.sol create mode 100644 examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes_standard_input.json create mode 100644 examples/test/semanticTests/literals_escape/escape.sol create mode 100644 examples/test/semanticTests/literals_escape/escape_standard_input.json create mode 100644 examples/test/semanticTests/literals_ether/ether.sol create mode 100644 examples/test/semanticTests/literals_ether/ether_standard_input.json create mode 100644 examples/test/semanticTests/literals_fractional_denominations/fractional_denominations.sol create mode 100644 examples/test/semanticTests/literals_fractional_denominations/fractional_denominations_standard_input.json create mode 100644 examples/test/semanticTests/literals_gwei/gwei.sol create mode 100644 examples/test/semanticTests/literals_gwei/gwei_standard_input.json create mode 100644 examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters.sol create mode 100644 examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters_standard_input.json create mode 100644 examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore.sol create mode 100644 examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore_standard_input.json create mode 100644 examples/test/semanticTests/literals_scientific_notation/scientific_notation.sol create mode 100644 examples/test/semanticTests/literals_scientific_notation/scientific_notation_standard_input.json create mode 100644 examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow.sol create mode 100644 examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow_standard_input.json create mode 100644 examples/test/semanticTests/literals_wei/wei.sol create mode 100644 examples/test/semanticTests/literals_wei/wei_standard_input.json create mode 100644 examples/test/semanticTests/memoryManagement_assembly_access/assembly_access.sol create mode 100644 examples/test/semanticTests/memoryManagement_assembly_access/assembly_access_standard_input.json create mode 100644 examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation.sol create mode 100644 examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation_standard_input.json create mode 100644 examples/test/semanticTests/memoryManagement_return_variable/return_variable.sol create mode 100644 examples/test/semanticTests/memoryManagement_return_variable/return_variable_standard_input.json create mode 100644 examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation.sol create mode 100644 examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation_standard_input.json create mode 100644 examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation.sol create mode 100644 examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation_standard_input.json create mode 100644 examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract.sol create mode 100644 examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name.sol create mode 100644 examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name.sol create mode 100644 examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier.sol create mode 100644 examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier.sol create mode 100644 examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_evaluation_order/evaluation_order.sol create mode 100644 examples/test/semanticTests/modifiers_evaluation_order/evaluation_order_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier/function_modifier.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier/function_modifier_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference.sol create mode 100644 examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter.sol create mode 100644 examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex.sol create mode 100644 examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive.sol create mode 100644 examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice.sol create mode 100644 examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return.sol create mode 100644 examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context.sol create mode 100644 examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier.sol create mode 100644 examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier.sol create mode 100644 examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers.sol create mode 100644 examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers_standard_input.json create mode 100644 examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type.sol create mode 100644 examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_circular_import/circular_import.sol create mode 100644 examples/test/semanticTests/multiSource_circular_import/circular_import_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_circular_import_2/circular_import_2.sol create mode 100644 examples/test/semanticTests/multiSource_circular_import_2/circular_import_2_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_circular_reimport/circular_reimport.sol create mode 100644 examples/test/semanticTests/multiSource_circular_reimport/circular_reimport_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2.sol create mode 100644 examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types.sol create mode 100644 examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract.sol create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual.sol create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super.sol create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive.sol create mode 100644 examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import.sol create mode 100644 examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_import/import.sol create mode 100644 examples/test/semanticTests/multiSource_import/import_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function.sol create mode 100644 examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias.sol create mode 100644 examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call.sol create mode 100644 examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call_standard_input.json create mode 100644 examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function.sol create mode 100644 examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function_standard_input.json create mode 100644 examples/test/semanticTests/operators_compound_assign/compound_assign.sol create mode 100644 examples/test/semanticTests/operators_compound_assign/compound_assign_standard_input.json create mode 100644 examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage.sol create mode 100644 examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople.sol create mode 100644 examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined.sol create mode 100644 examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople.sol create mode 100644 examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_left/shift_left.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_left/shift_left_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right/shift_right.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right/shift_right_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue.sol create mode 100644 examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue_standard_input.json create mode 100644 examples/test/semanticTests/operators_shifts_shifts/shifts.sol create mode 100644 examples/test/semanticTests/operators_shifts_shifts/shifts_standard_input.json create mode 100644 examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement.sol create mode 100644 examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators.sol create mode 100644 examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators.sol create mode 100644 examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function.sol create mode 100644 examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators.sol create mode 100644 examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations.sol create mode 100644 examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators.sol create mode 100644 examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives.sol create mode 100644 examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive.sol create mode 100644 examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup.sol create mode 100644 examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator.sol create mode 100644 examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator_standard_input.json create mode 100644 examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators.sol create mode 100644 examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators_standard_input.json create mode 100644 examples/test/semanticTests/optimizer_shift_bytes/shift_bytes.sol create mode 100644 examples/test/semanticTests/optimizer_shift_bytes/shift_bytes_standard_input.json create mode 100644 examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier.sol create mode 100644 examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier_standard_input.json create mode 100644 examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive.sol create mode 100644 examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive_standard_input.json create mode 100644 examples/test/semanticTests/receive_ether_and_data/ether_and_data.sol create mode 100644 examples/test/semanticTests/receive_ether_and_data/ether_and_data_standard_input.json create mode 100644 examples/test/semanticTests/receive_inherited/inherited.sol create mode 100644 examples/test/semanticTests/receive_inherited/inherited_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_array_slices/array_slices.sol create mode 100644 examples/test/semanticTests/revertStrings_array_slices/array_slices_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_bubble/bubble.sol create mode 100644 examples/test/semanticTests/revertStrings_bubble/bubble_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1.sol create mode 100644 examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code.sol create mode 100644 examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_empty_v1/empty_v1.sol create mode 100644 examples/test/semanticTests/revertStrings_empty_v1/empty_v1_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_empty_v2/empty_v2.sol create mode 100644 examples/test/semanticTests/revertStrings_empty_v2/empty_v2_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_enum_v1/enum_v1.sol create mode 100644 examples/test/semanticTests/revertStrings_enum_v1/enum_v1_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_enum_v2/enum_v2.sol create mode 100644 examples/test/semanticTests/revertStrings_enum_v2/enum_v2_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function.sol create mode 100644 examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1.sol create mode 100644 examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2.sol create mode 100644 examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1.sol create mode 100644 examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1.sol create mode 100644 examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call.sol create mode 100644 examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_short_input_array/short_input_array.sol create mode 100644 examples/test/semanticTests/revertStrings_short_input_array/short_input_array_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes.sol create mode 100644 examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_transfer/transfer.sol create mode 100644 examples/test/semanticTests/revertStrings_transfer/transfer_standard_input.json create mode 100644 examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback.sol create mode 100644 examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback_standard_input.json create mode 100644 examples/test/semanticTests/reverts_assert_require/assert_require.sol create mode 100644 examples/test/semanticTests/reverts_assert_require/assert_require_standard_input.json create mode 100644 examples/test/semanticTests/reverts_error_struct/error_struct.sol create mode 100644 examples/test/semanticTests/reverts_error_struct/error_struct_standard_input.json create mode 100644 examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg.sol create mode 100644 examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg_standard_input.json create mode 100644 examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret.sol create mode 100644 examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret_standard_input.json create mode 100644 examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared.sol create mode 100644 examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared_standard_input.json create mode 100644 examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored.sol create mode 100644 examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored_standard_input.json create mode 100644 examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction.sol create mode 100644 examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction_standard_input.json create mode 100644 examples/test/semanticTests/reverts_revert/revert.sol create mode 100644 examples/test/semanticTests/reverts_revert/revert_standard_input.json create mode 100644 examples/test/semanticTests/reverts_revert_return_area/revert_return_area.sol create mode 100644 examples/test/semanticTests/reverts_revert_return_area/revert_return_area_standard_input.json create mode 100644 examples/test/semanticTests/reverts_simple_throw/simple_throw.sol create mode 100644 examples/test/semanticTests/reverts_simple_throw/simple_throw_standard_input.json create mode 100644 examples/test/semanticTests/salted_create_prediction_example/prediction_example.sol create mode 100644 examples/test/semanticTests/salted_create_prediction_example/prediction_example_standard_input.json create mode 100644 examples/test/semanticTests/salted_create_salted_create/salted_create.sol create mode 100644 examples/test/semanticTests/salted_create_salted_create/salted_create_standard_input.json create mode 100644 examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value.sol create mode 100644 examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value_standard_input.json create mode 100644 examples/test/semanticTests/shanghai_evmone_support/evmone_support.sol create mode 100644 examples/test/semanticTests/shanghai_evmone_support/evmone_support_standard_input.json create mode 100644 examples/test/semanticTests/shanghai_push0/push0.sol create mode 100644 examples/test/semanticTests/shanghai_push0/push0_standard_input.json create mode 100644 examples/test/semanticTests/smoke_alignment/alignment.sol create mode 100644 examples/test/semanticTests/smoke_alignment/alignment_standard_input.json create mode 100644 examples/test/semanticTests/smoke_arrays/arrays.sol create mode 100644 examples/test/semanticTests/smoke_arrays/arrays_standard_input.json create mode 100644 examples/test/semanticTests/smoke_basic/basic.sol create mode 100644 examples/test/semanticTests/smoke_basic/basic_standard_input.json create mode 100644 examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings.sol create mode 100644 examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings_standard_input.json create mode 100644 examples/test/semanticTests/smoke_constructor/constructor.sol create mode 100644 examples/test/semanticTests/smoke_constructor/constructor_standard_input.json create mode 100644 examples/test/semanticTests/smoke_failure/failure.sol create mode 100644 examples/test/semanticTests/smoke_failure/failure_standard_input.json create mode 100644 examples/test/semanticTests/smoke_fallback/fallback.sol create mode 100644 examples/test/semanticTests/smoke_fallback/fallback_standard_input.json create mode 100644 examples/test/semanticTests/smoke_multiline/multiline.sol create mode 100644 examples/test/semanticTests/smoke_multiline/multiline_standard_input.json create mode 100644 examples/test/semanticTests/smoke_multiline_comments/multiline_comments.sol create mode 100644 examples/test/semanticTests/smoke_multiline_comments/multiline_comments_standard_input.json create mode 100644 examples/test/semanticTests/smoke_structs/structs.sol create mode 100644 examples/test/semanticTests/smoke_structs/structs_standard_input.json create mode 100644 examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string.sol create mode 100644 examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string_standard_input.json create mode 100644 examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access.sol create mode 100644 examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access_standard_input.json create mode 100644 examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized.sol create mode 100644 examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized_standard_input.json create mode 100644 examples/test/semanticTests/state_blobhash/blobhash.sol create mode 100644 examples/test/semanticTests/state_blobhash/blobhash_standard_input.json create mode 100644 examples/test/semanticTests/state_block_basefee/block_basefee.sol create mode 100644 examples/test/semanticTests/state_block_basefee/block_basefee_standard_input.json create mode 100644 examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee.sol create mode 100644 examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee_standard_input.json create mode 100644 examples/test/semanticTests/state_block_chainid/block_chainid.sol create mode 100644 examples/test/semanticTests/state_block_chainid/block_chainid_standard_input.json create mode 100644 examples/test/semanticTests/state_block_coinbase/block_coinbase.sol create mode 100644 examples/test/semanticTests/state_block_coinbase/block_coinbase_standard_input.json create mode 100644 examples/test/semanticTests/state_block_difficulty/block_difficulty.sol create mode 100644 examples/test/semanticTests/state_block_difficulty/block_difficulty_standard_input.json create mode 100644 examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris.sol create mode 100644 examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris_standard_input.json create mode 100644 examples/test/semanticTests/state_block_gaslimit/block_gaslimit.sol create mode 100644 examples/test/semanticTests/state_block_gaslimit/block_gaslimit_standard_input.json create mode 100644 examples/test/semanticTests/state_block_number/block_number.sol create mode 100644 examples/test/semanticTests/state_block_number/block_number_standard_input.json create mode 100644 examples/test/semanticTests/state_block_prevrandao/block_prevrandao.sol create mode 100644 examples/test/semanticTests/state_block_prevrandao/block_prevrandao_standard_input.json create mode 100644 examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris.sol create mode 100644 examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris_standard_input.json create mode 100644 examples/test/semanticTests/state_block_timestamp/block_timestamp.sol create mode 100644 examples/test/semanticTests/state_block_timestamp/block_timestamp_standard_input.json create mode 100644 examples/test/semanticTests/state_blockhash_basic/blockhash_basic.sol create mode 100644 examples/test/semanticTests/state_blockhash_basic/blockhash_basic_standard_input.json create mode 100644 examples/test/semanticTests/state_gasleft/gasleft.sol create mode 100644 examples/test/semanticTests/state_gasleft/gasleft_standard_input.json create mode 100644 examples/test/semanticTests/state_msg_data/msg_data.sol create mode 100644 examples/test/semanticTests/state_msg_data/msg_data_standard_input.json create mode 100644 examples/test/semanticTests/state_msg_sender/msg_sender.sol create mode 100644 examples/test/semanticTests/state_msg_sender/msg_sender_standard_input.json create mode 100644 examples/test/semanticTests/state_msg_sig/msg_sig.sol create mode 100644 examples/test/semanticTests/state_msg_sig/msg_sig_standard_input.json create mode 100644 examples/test/semanticTests/state_msg_value/msg_value.sol create mode 100644 examples/test/semanticTests/state_msg_value/msg_value_standard_input.json create mode 100644 examples/test/semanticTests/state_tx_gasprice/tx_gasprice.sol create mode 100644 examples/test/semanticTests/state_tx_gasprice/tx_gasprice_standard_input.json create mode 100644 examples/test/semanticTests/state_tx_origin/tx_origin.sol create mode 100644 examples/test/semanticTests/state_tx_origin/tx_origin_standard_input.json create mode 100644 examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash.sol create mode 100644 examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash_standard_input.json create mode 100644 examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash.sol create mode 100644 examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash_standard_input.json create mode 100644 examples/test/semanticTests/state_var_initialization_1/state_var_initialization.sol create mode 100644 examples/test/semanticTests/state_var_initialization_1/state_var_initialization_standard_input.json create mode 100644 examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order.sol create mode 100644 examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order_standard_input.json create mode 100644 examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2.sol create mode 100644 examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2_standard_input.json create mode 100644 examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3.sol create mode 100644 examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3_standard_input.json create mode 100644 examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue.sol create mode 100644 examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue_standard_input.json create mode 100644 examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array.sol create mode 100644 examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array_standard_input.json create mode 100644 examples/test/semanticTests/storage_array_accessor/array_accessor.sol create mode 100644 examples/test/semanticTests/storage_array_accessor/array_accessor_standard_input.json create mode 100644 examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits.sol create mode 100644 examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits_standard_input.json create mode 100644 examples/test/semanticTests/storage_complex_accessors/complex_accessors.sol create mode 100644 examples/test/semanticTests/storage_complex_accessors/complex_accessors_standard_input.json create mode 100644 examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty.sol create mode 100644 examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty_standard_input.json create mode 100644 examples/test/semanticTests/storage_mapping_state/mapping_state.sol create mode 100644 examples/test/semanticTests/storage_mapping_state/mapping_state_standard_input.json create mode 100644 examples/test/semanticTests/storage_mapping_string_key/mapping_string_key.sol create mode 100644 examples/test/semanticTests/storage_mapping_string_key/mapping_string_key_standard_input.json create mode 100644 examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete.sol create mode 100644 examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete_standard_input.json create mode 100644 examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete.sol create mode 100644 examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete_standard_input.json create mode 100644 examples/test/semanticTests/storage_packed_functions/packed_functions.sol create mode 100644 examples/test/semanticTests/storage_packed_functions/packed_functions_standard_input.json create mode 100644 examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow.sol create mode 100644 examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow_standard_input.json create mode 100644 examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed.sol create mode 100644 examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed_standard_input.json create mode 100644 examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes.sol create mode 100644 examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes_standard_input.json create mode 100644 examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum.sol create mode 100644 examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum_standard_input.json create mode 100644 examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint.sol create mode 100644 examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint_standard_input.json create mode 100644 examples/test/semanticTests/storage_simple_accessor/simple_accessor.sol create mode 100644 examples/test/semanticTests/storage_simple_accessor/simple_accessor_standard_input.json create mode 100644 examples/test/semanticTests/storage_state_smoke_test/state_smoke_test.sol create mode 100644 examples/test/semanticTests/storage_state_smoke_test/state_smoke_test_standard_input.json create mode 100644 examples/test/semanticTests/storage_struct_accessor/struct_accessor.sol create mode 100644 examples/test/semanticTests/storage_struct_accessor/struct_accessor_standard_input.json create mode 100644 examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args.sol create mode 100644 examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args_standard_input.json create mode 100644 examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types.sol create mode 100644 examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types_standard_input.json create mode 100644 examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list.sol create mode 100644 examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list_standard_input.json create mode 100644 examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings.sol create mode 100644 examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings_standard_input.json create mode 100644 examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested.sol create mode 100644 examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested_standard_input.json create mode 100644 examples/test/semanticTests/strings_constant_string_literal/constant_string_literal.sol create mode 100644 examples/test/semanticTests/strings_constant_string_literal/constant_string_literal_standard_input.json create mode 100644 examples/test/semanticTests/strings_empty_storage_string/empty_storage_string.sol create mode 100644 examples/test/semanticTests/strings_empty_storage_string/empty_storage_string_standard_input.json create mode 100644 examples/test/semanticTests/strings_empty_string/empty_string.sol create mode 100644 examples/test/semanticTests/strings_empty_string/empty_string_standard_input.json create mode 100644 examples/test/semanticTests/strings_empty_string_input/empty_string_input.sol create mode 100644 examples/test/semanticTests/strings_empty_string_input/empty_string_input_standard_input.json create mode 100644 examples/test/semanticTests/strings_return_string/return_string.sol create mode 100644 examples/test/semanticTests/strings_return_string/return_string_standard_input.json create mode 100644 examples/test/semanticTests/strings_string_escapes/string_escapes.sol create mode 100644 examples/test/semanticTests/strings_string_escapes/string_escapes_standard_input.json create mode 100644 examples/test/semanticTests/strings_unicode_escapes/unicode_escapes.sol create mode 100644 examples/test/semanticTests/strings_unicode_escapes/unicode_escapes_standard_input.json create mode 100644 examples/test/semanticTests/strings_unicode_string/unicode_string.sol create mode 100644 examples/test/semanticTests/strings_unicode_string/unicode_string_standard_input.json create mode 100644 examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct.sol create mode 100644 examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs.sol create mode 100644 examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested.sol create mode 100644 examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested_standard_input.json create mode 100644 examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded.sol create mode 100644 examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded_standard_input.json create mode 100644 examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory.sol create mode 100644 examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex.sol create mode 100644 examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping.sol create mode 100644 examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_from_storage/copy_from_storage.sol create mode 100644 examples/test/semanticTests/structs_copy_from_storage/copy_from_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage.sol create mode 100644 examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory.sol create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage.sol create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory.sol create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage.sol create mode 100644 examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping.sol create mode 100644 examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping.sol create mode 100644 examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping.sol create mode 100644 examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/structs_delete_struct/delete_struct.sol create mode 100644 examples/test/semanticTests/structs_delete_struct/delete_struct_standard_input.json create mode 100644 examples/test/semanticTests/structs_event/event.sol create mode 100644 examples/test/semanticTests/structs_event/event_standard_input.json create mode 100644 examples/test/semanticTests/structs_function_type_copy/function_type_copy.sol create mode 100644 examples/test/semanticTests/structs_function_type_copy/function_type_copy_standard_input.json create mode 100644 examples/test/semanticTests/structs_global/global.sol create mode 100644 examples/test/semanticTests/structs_global/global_standard_input.json create mode 100644 examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type.sol create mode 100644 examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type_standard_input.json create mode 100644 examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor.sol create mode 100644 examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor_standard_input.json create mode 100644 examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args.sol create mode 100644 examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args_standard_input.json create mode 100644 examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested.sol create mode 100644 examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested_standard_input.json create mode 100644 examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load.sol create mode 100644 examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load_standard_input.json create mode 100644 examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write.sol create mode 100644 examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write_standard_input.json create mode 100644 examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy.sol create mode 100644 examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy_standard_input.json create mode 100644 examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation.sol create mode 100644 examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation_standard_input.json create mode 100644 examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation.sol create mode 100644 examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation_standard_input.json create mode 100644 examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete.sol create mode 100644 examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete_standard_input.json create mode 100644 examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2.sol create mode 100644 examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2_standard_input.json create mode 100644 examples/test/semanticTests/structs_recursive_structs/recursive_structs.sol create mode 100644 examples/test/semanticTests/structs_recursive_structs/recursive_structs_standard_input.json create mode 100644 examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation.sol create mode 100644 examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct.sol create mode 100644 examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested.sol create mode 100644 examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete.sol create mode 100644 examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_copy/struct_copy.sol create mode 100644 examples/test/semanticTests/structs_struct_copy/struct_copy_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local.sol create mode 100644 examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_member/struct_delete_member.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_member/struct_delete_member_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping.sol create mode 100644 examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage.sol create mode 100644 examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr.sol create mode 100644 examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor.sol create mode 100644 examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_reference/struct_reference.sol create mode 100644 examples/test/semanticTests/structs_struct_reference/struct_reference_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_referencing/struct_referencing.sol create mode 100644 examples/test/semanticTests/structs_struct_referencing/struct_referencing_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value.sol create mode 100644 examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping.sol create mode 100644 examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory.sol create mode 100644 examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr.sol create mode 100644 examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr_standard_input.json create mode 100644 examples/test/semanticTests/structs_structs/structs.sol create mode 100644 examples/test/semanticTests/structs_structs/structs_standard_input.json create mode 100644 examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct.sol create mode 100644 examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_assert/assert.sol create mode 100644 examples/test/semanticTests/tryCatch_assert/assert_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_create/create.sol create mode 100644 examples/test/semanticTests/tryCatch_create/create_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding.sol create mode 100644 examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_lowLevel/lowLevel.sol create mode 100644 examples/test/semanticTests/tryCatch_lowLevel/lowLevel_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_malformed_error/malformed_error.sol create mode 100644 examples/test/semanticTests/tryCatch_malformed_error/malformed_error_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic.sol create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2.sol create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3.sol create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4.sol create mode 100644 examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_nested/nested.sol create mode 100644 examples/test/semanticTests/tryCatch_nested/nested_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_panic/panic.sol create mode 100644 examples/test/semanticTests/tryCatch_panic/panic_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_return_function/return_function.sol create mode 100644 examples/test/semanticTests/tryCatch_return_function/return_function_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_simple/simple.sol create mode 100644 examples/test/semanticTests/tryCatch_simple/simple_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple.sol create mode 100644 examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_structured/structured.sol create mode 100644 examples/test/semanticTests/tryCatch_structured/structured_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel.sol create mode 100644 examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_super_trivial/super_trivial.sol create mode 100644 examples/test/semanticTests/tryCatch_super_trivial/super_trivial_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_trivial/trivial.sol create mode 100644 examples/test/semanticTests/tryCatch_trivial/trivial_standard_input.json create mode 100644 examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call.sol create mode 100644 examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call_standard_input.json create mode 100644 examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param.sol create mode 100644 examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param_standard_input.json create mode 100644 examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type.sol create mode 100644 examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size.sol create mode 100644 examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size.sol create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size.sol create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size.sol create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size_standard_input.json create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size.sol create mode 100644 examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size_standard_input.json create mode 100644 examples/test/semanticTests/types_external_function_to_address/external_function_to_address.sol create mode 100644 examples/test/semanticTests/types_external_function_to_address/external_function_to_address_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param.sol create mode 100644 examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key.sol create mode 100644 examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter.sol create mode 100644 examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library.sol create mode 100644 examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping.sol create mode 100644 examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping.sol create mode 100644 examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1.sol create mode 100644 examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2.sol create mode 100644 examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1.sol create mode 100644 examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2.sol create mode 100644 examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1.sol create mode 100644 examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2.sol create mode 100644 examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_simple/mapping_simple.sol create mode 100644 examples/test/semanticTests/types_mapping_simple/mapping_simple_standard_input.json create mode 100644 examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage.sol create mode 100644 examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage_standard_input.json create mode 100644 examples/test/semanticTests/types_nested_tuples/nested_tuples.sol create mode 100644 examples/test/semanticTests/types_nested_tuples/nested_tuples_standard_input.json create mode 100644 examples/test/semanticTests/types_packing_signed_types/packing_signed_types.sol create mode 100644 examples/test/semanticTests/types_packing_signed_types/packing_signed_types_standard_input.json create mode 100644 examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types.sol create mode 100644 examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types_standard_input.json create mode 100644 examples/test/semanticTests/types_strings/strings.sol create mode 100644 examples/test/semanticTests/types_strings/strings_standard_input.json create mode 100644 examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param.sol create mode 100644 examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param_standard_input.json create mode 100644 examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow.sol create mode 100644 examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow_standard_input.json create mode 100644 examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup.sol create mode 100644 examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup_standard_input.json create mode 100644 examples/test/semanticTests/underscore_as_function/as_function.sol create mode 100644 examples/test/semanticTests/underscore_as_function/as_function_standard_input.json create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor.sol create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor_standard_input.json create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor.sol create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor_standard_input.json create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_store2/store2.sol create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_store2/store2_standard_input.json create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor.sol create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor_standard_input.json create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy.sol create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy_standard_input.json create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul.sol create mode 100644 examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul_standard_input.json create mode 100644 examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug.sol create mode 100644 examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_abicodec/abicodec.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_abicodec/abicodec_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_calldata/calldata.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_calldata/calldata_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_cleanup/cleanup.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_cleanup/cleanup_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_constant/constant.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_constant/constant_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_conversion/conversion.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_conversion/conversion_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_erc20/erc20.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_erc20/erc20_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_multisource/multisource.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_multisource/multisource_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_ownable/ownable.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_ownable/ownable_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_parameter/parameter.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_parameter/parameter_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_simple/simple.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_simple/simple_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary_standard_input.json create mode 100644 examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined.sol create mode 100644 examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined_standard_input.json create mode 100644 examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy.sol create mode 100644 examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy_standard_input.json create mode 100644 examples/test/semanticTests/using_free_function_braces/free_function_braces.sol create mode 100644 examples/test/semanticTests/using_free_function_braces/free_function_braces_standard_input.json create mode 100644 examples/test/semanticTests/using_free_function_multi/free_function_multi.sol create mode 100644 examples/test/semanticTests/using_free_function_multi/free_function_multi_standard_input.json create mode 100644 examples/test/semanticTests/using_free_functions_individual/free_functions_individual.sol create mode 100644 examples/test/semanticTests/using_free_functions_individual/free_functions_individual_standard_input.json create mode 100644 examples/test/semanticTests/using_imported_functions/imported_functions.sol create mode 100644 examples/test/semanticTests/using_imported_functions/imported_functions_standard_input.json create mode 100644 examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract.sol create mode 100644 examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract_standard_input.json create mode 100644 examples/test/semanticTests/using_library_on_interface/library_on_interface.sol create mode 100644 examples/test/semanticTests/using_library_on_interface/library_on_interface_standard_input.json create mode 100644 examples/test/semanticTests/using_library_through_module/library_through_module.sol create mode 100644 examples/test/semanticTests/using_library_through_module/library_through_module_standard_input.json create mode 100644 examples/test/semanticTests/using_module_renamed/module_renamed.sol create mode 100644 examples/test/semanticTests/using_module_renamed/module_renamed_standard_input.json create mode 100644 examples/test/semanticTests/using_private_library_function/private_library_function.sol create mode 100644 examples/test/semanticTests/using_private_library_function/private_library_function_standard_input.json create mode 100644 examples/test/semanticTests/using_recursive_import/recursive_import.sol create mode 100644 examples/test/semanticTests/using_recursive_import/recursive_import_standard_input.json create mode 100644 examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types.sol create mode 100644 examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types_standard_input.json create mode 100644 examples/test/semanticTests/using_using_global_for_global/using_global_for_global.sol create mode 100644 examples/test/semanticTests/using_using_global_for_global/using_global_for_global_standard_input.json create mode 100644 examples/test/semanticTests/using_using_global_invisible/using_global_invisible.sol create mode 100644 examples/test/semanticTests/using_using_global_invisible/using_global_invisible_standard_input.json create mode 100644 examples/test/semanticTests/using_using_global_library/using_global_library.sol create mode 100644 examples/test/semanticTests/using_using_global_library/using_global_library_standard_input.json create mode 100644 examples/test/semanticTests/variables_delete_local/delete_local.sol create mode 100644 examples/test/semanticTests/variables_delete_local/delete_local_standard_input.json create mode 100644 examples/test/semanticTests/variables_delete_locals/delete_locals.sol create mode 100644 examples/test/semanticTests/variables_delete_locals/delete_locals_standard_input.json create mode 100644 examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable.sol create mode 100644 examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable_standard_input.json create mode 100644 examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset.sol create mode 100644 examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset_standard_input.json create mode 100644 examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment.sol create mode 100644 examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment_standard_input.json create mode 100644 examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment.sol create mode 100644 examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment_standard_input.json create mode 100644 examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment.sol create mode 100644 examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment_standard_input.json create mode 100644 examples/test/semanticTests/variables_public_state_overridding/public_state_overridding.sol create mode 100644 examples/test/semanticTests/variables_public_state_overridding/public_state_overridding_standard_input.json create mode 100644 examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct.sol create mode 100644 examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct_standard_input.json create mode 100644 examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct.sol create mode 100644 examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct_standard_input.json create mode 100644 examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean.sol create mode 100644 examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable.sol create mode 100644 examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members.sol create mode 100644 examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable.sol create mode 100644 examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable/transient_state_variable.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable/transient_state_variable_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment_standard_input.json create mode 100644 examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt.sol create mode 100644 examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt_standard_input.json create mode 100644 examples/test/semanticTests/various_address_code/address_code.sol create mode 100644 examples/test/semanticTests/various_address_code/address_code_standard_input.json create mode 100644 examples/test/semanticTests/various_address_code_complex/address_code_complex.sol create mode 100644 examples/test/semanticTests/various_address_code_complex/address_code_complex_standard_input.json create mode 100644 examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression.sol create mode 100644 examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression_standard_input.json create mode 100644 examples/test/semanticTests/various_balance/balance.sol create mode 100644 examples/test/semanticTests/various_balance/balance_standard_input.json create mode 100644 examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug.sol create mode 100644 examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug_standard_input.json create mode 100644 examples/test/semanticTests/various_code_access_content/code_access_content.sol create mode 100644 examples/test/semanticTests/various_code_access_content/code_access_content_standard_input.json create mode 100644 examples/test/semanticTests/various_code_access_create/code_access_create.sol create mode 100644 examples/test/semanticTests/various_code_access_create/code_access_create_standard_input.json create mode 100644 examples/test/semanticTests/various_code_access_padding/code_access_padding.sol create mode 100644 examples/test/semanticTests/various_code_access_padding/code_access_padding_standard_input.json create mode 100644 examples/test/semanticTests/various_code_access_runtime/code_access_runtime.sol create mode 100644 examples/test/semanticTests/various_code_access_runtime/code_access_runtime_standard_input.json create mode 100644 examples/test/semanticTests/various_code_length/code_length.sol create mode 100644 examples/test/semanticTests/various_code_length/code_length_standard_input.json create mode 100644 examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member.sol create mode 100644 examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member_standard_input.json create mode 100644 examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly.sol create mode 100644 examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly_standard_input.json create mode 100644 examples/test/semanticTests/various_codehash/codehash.sol create mode 100644 examples/test/semanticTests/various_codehash/codehash_standard_input.json create mode 100644 examples/test/semanticTests/various_codehash_assembly/codehash_assembly.sol create mode 100644 examples/test/semanticTests/various_codehash_assembly/codehash_assembly_standard_input.json create mode 100644 examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies.sol create mode 100644 examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies_standard_input.json create mode 100644 examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack.sol create mode 100644 examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack_standard_input.json create mode 100644 examples/test/semanticTests/various_create_calldata/create_calldata.sol create mode 100644 examples/test/semanticTests/various_create_calldata/create_calldata_standard_input.json create mode 100644 examples/test/semanticTests/various_create_random/create_random.sol create mode 100644 examples/test/semanticTests/various_create_random/create_random_standard_input.json create mode 100644 examples/test/semanticTests/various_cross_contract_types/cross_contract_types.sol create mode 100644 examples/test/semanticTests/various_cross_contract_types/cross_contract_types_standard_input.json create mode 100644 examples/test/semanticTests/various_decayed_tuple/decayed_tuple.sol create mode 100644 examples/test/semanticTests/various_decayed_tuple/decayed_tuple_standard_input.json create mode 100644 examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment.sol create mode 100644 examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment_standard_input.json create mode 100644 examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient.sol create mode 100644 examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient_standard_input.json create mode 100644 examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter.sol create mode 100644 examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter_standard_input.json create mode 100644 examples/test/semanticTests/various_erc20/erc20.sol create mode 100644 examples/test/semanticTests/various_erc20/erc20_standard_input.json create mode 100644 examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls.sol create mode 100644 examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls_standard_input.json create mode 100644 examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests.sol create mode 100644 examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests_standard_input.json create mode 100644 examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease.sol create mode 100644 examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease_standard_input.json create mode 100644 examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution.sol create mode 100644 examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution_standard_input.json create mode 100644 examples/test/semanticTests/various_inline_member_init/inline_member_init.sol create mode 100644 examples/test/semanticTests/various_inline_member_init/inline_member_init_standard_input.json create mode 100644 examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence.sol create mode 100644 examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence_standard_input.json create mode 100644 examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers.sol create mode 100644 examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers_standard_input.json create mode 100644 examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct.sol create mode 100644 examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct_standard_input.json create mode 100644 examples/test/semanticTests/various_literal_empty_string/literal_empty_string.sol create mode 100644 examples/test/semanticTests/various_literal_empty_string/literal_empty_string_standard_input.json create mode 100644 examples/test/semanticTests/various_many_subassemblies/many_subassemblies.sol create mode 100644 examples/test/semanticTests/various_many_subassemblies/many_subassemblies_standard_input.json create mode 100644 examples/test/semanticTests/various_memory_overwrite/memory_overwrite.sol create mode 100644 examples/test/semanticTests/various_memory_overwrite/memory_overwrite_standard_input.json create mode 100644 examples/test/semanticTests/various_multi_modifiers/multi_modifiers.sol create mode 100644 examples/test/semanticTests/various_multi_modifiers/multi_modifiers_standard_input.json create mode 100644 examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration.sol create mode 100644 examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration_standard_input.json create mode 100644 examples/test/semanticTests/various_negative_stack_height/negative_stack_height.sol create mode 100644 examples/test/semanticTests/various_negative_stack_height/negative_stack_height_standard_input.json create mode 100644 examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct.sol create mode 100644 examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct_standard_input.json create mode 100644 examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory.sol create mode 100644 examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory_standard_input.json create mode 100644 examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed.sol create mode 100644 examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed_standard_input.json create mode 100644 examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun.sol create mode 100644 examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun_standard_input.json create mode 100644 examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries.sol create mode 100644 examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries_standard_input.json create mode 100644 examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy.sol create mode 100644 examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy_standard_input.json create mode 100644 examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun.sol create mode 100644 examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun_standard_input.json create mode 100644 examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries.sol create mode 100644 examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries_standard_input.json create mode 100644 examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy.sol create mode 100644 examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy_standard_input.json create mode 100644 examples/test/semanticTests/various_senders_balance/senders_balance.sol create mode 100644 examples/test/semanticTests/various_senders_balance/senders_balance_standard_input.json create mode 100644 examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance.sol create mode 100644 examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance_standard_input.json create mode 100644 examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types.sol create mode 100644 examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types_standard_input.json create mode 100644 examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol create mode 100644 examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements_standard_input.json create mode 100644 examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs.sol create mode 100644 examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs_standard_input.json create mode 100644 examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture.sol create mode 100644 examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture_standard_input.json create mode 100644 examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name.sol create mode 100644 examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name_standard_input.json create mode 100644 examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure.sol create mode 100644 examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure_standard_input.json create mode 100644 examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium.sol create mode 100644 examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium_standard_input.json create mode 100644 examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable.sol create mode 100644 examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable_standard_input.json create mode 100644 examples/test/semanticTests/various_store_bytes/store_bytes.sol create mode 100644 examples/test/semanticTests/various_store_bytes/store_bytes_standard_input.json create mode 100644 examples/test/semanticTests/various_string_tuples/string_tuples.sol create mode 100644 examples/test/semanticTests/various_string_tuples/string_tuples_standard_input.json create mode 100644 examples/test/semanticTests/various_super/super.sol create mode 100644 examples/test/semanticTests/various_super/super_standard_input.json create mode 100644 examples/test/semanticTests/various_super_alone/super_alone.sol create mode 100644 examples/test/semanticTests/various_super_alone/super_alone_standard_input.json create mode 100644 examples/test/semanticTests/various_super_parentheses/super_parentheses.sol create mode 100644 examples/test/semanticTests/various_super_parentheses/super_parentheses_standard_input.json create mode 100644 examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite.sol create mode 100644 examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite_standard_input.json create mode 100644 examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex.sol create mode 100644 examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex_standard_input.json create mode 100644 examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock.sol create mode 100644 examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock_standard_input.json create mode 100644 examples/test/semanticTests/various_tuples/tuples.sol create mode 100644 examples/test/semanticTests/various_tuples/tuples_standard_input.json create mode 100644 examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration.sol create mode 100644 examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration_standard_input.json create mode 100644 examples/test/semanticTests/various_value_complex/value_complex.sol create mode 100644 examples/test/semanticTests/various_value_complex/value_complex_standard_input.json create mode 100644 examples/test/semanticTests/various_value_insane/value_insane.sol create mode 100644 examples/test/semanticTests/various_value_insane/value_insane_standard_input.json create mode 100644 examples/test/semanticTests/various_write_storage_external/write_storage_external.sol create mode 100644 examples/test/semanticTests/various_write_storage_external/write_storage_external_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_assert/assert.sol create mode 100644 examples/test/semanticTests/viaYul_assert/assert_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_assert_and_require/assert_and_require.sol create mode 100644 examples/test/semanticTests/viaYul_assert_and_require/assert_and_require_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call.sol create mode 100644 examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic.sol create mode 100644 examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_cleanup_comparison/comparison.sol create mode 100644 examples/test/semanticTests/viaYul_cleanup_comparison/comparison_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_comparison/comparison.sol create mode 100644 examples/test/semanticTests/viaYul_comparison/comparison_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_comparison_functions/comparison_functions.sol create mode 100644 examples/test/semanticTests/viaYul_comparison_functions/comparison_functions_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple.sol create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal.sol create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple.sol create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables.sol create mode 100644 examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_function_cast/function_cast.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_function_cast/function_cast_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug.sol create mode 100644 examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call.sol create mode 100644 examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_delete/delete.sol create mode 100644 examples/test/semanticTests/viaYul_delete/delete_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow.sol create mode 100644 examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed.sol create mode 100644 examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow.sol create mode 100644 examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero.sol create mode 100644 examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed.sol create mode 100644 examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow.sol create mode 100644 examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed.sol create mode 100644 examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow.sol create mode 100644 examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed.sol create mode 100644 examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct.sol create mode 100644 examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array.sol create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32.sol create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array.sol create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct.sol create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32.sol create mode 100644 examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer.sol create mode 100644 examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp/exp.sol create mode 100644 examples/test/semanticTests/viaYul_exp/exp_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp_literals/exp_literals.sol create mode 100644 examples/test/semanticTests/viaYul_exp_literals/exp_literals_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success.sol create mode 100644 examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp_neg/exp_neg.sol create mode 100644 examples/test/semanticTests/viaYul_exp_neg/exp_neg_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow.sol create mode 100644 examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp_overflow/exp_overflow.sol create mode 100644 examples/test/semanticTests/viaYul_exp_overflow/exp_overflow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_exp_various/exp_various.sol create mode 100644 examples/test/semanticTests/viaYul_exp_various/exp_various_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_function_address/function_address.sol create mode 100644 examples/test/semanticTests/viaYul_function_address/function_address_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks.sol create mode 100644 examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_function_pointers/function_pointers.sol create mode 100644 examples/test/semanticTests/viaYul_function_pointers/function_pointers_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_function_selector/function_selector.sol create mode 100644 examples/test/semanticTests/viaYul_function_selector/function_selector_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_if/if.sol create mode 100644 examples/test/semanticTests/viaYul_if/if_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_keccak/keccak.sol create mode 100644 examples/test/semanticTests/viaYul_keccak/keccak_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_local_assignment/local_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_local_assignment/local_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init.sol create mode 100644 examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_loops_break/break.sol create mode 100644 examples/test/semanticTests/viaYul_loops_break/break_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_loops_continue/continue.sol create mode 100644 examples/test/semanticTests/viaYul_loops_continue/continue_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_loops_return/return.sol create mode 100644 examples/test/semanticTests/viaYul_loops_return/return_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_loops_simple/simple.sol create mode 100644 examples/test/semanticTests/viaYul_loops_simple/simple_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter.sol create mode 100644 examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_mapping_getters/mapping_getters.sol create mode 100644 examples/test/semanticTests/viaYul_mapping_getters/mapping_getters_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key.sol create mode 100644 examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow.sol create mode 100644 examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_msg_sender/msg_sender.sol create mode 100644 examples/test/semanticTests/viaYul_msg_sender/msg_sender_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_negation_bug/negation_bug.sol create mode 100644 examples/test/semanticTests/viaYul_negation_bug/negation_bug_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_require/require.sol create mode 100644 examples/test/semanticTests/viaYul_require/require_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_return/return.sol create mode 100644 examples/test/semanticTests/viaYul_return/return_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_return_and_convert/return_and_convert.sol create mode 100644 examples/test/semanticTests/viaYul_return_and_convert/return_and_convert_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers.sol create mode 100644 examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_short_circuit/short_circuit.sol create mode 100644 examples/test/semanticTests/viaYul_short_circuit/short_circuit_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_simple_assignment/simple_assignment.sol create mode 100644 examples/test/semanticTests/viaYul_simple_assignment/simple_assignment_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm.sol create mode 100644 examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_smoke_test/smoke_test.sol create mode 100644 examples/test/semanticTests/viaYul_smoke_test/smoke_test_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes.sol create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long.sol create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array.sol create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array.sol create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct.sol create mode 100644 examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_mappings/mappings.sol create mode 100644 examples/test/semanticTests/viaYul_storage_mappings/mappings_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage.sol create mode 100644 examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage.sol create mode 100644 examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_string_format/string_format.sol create mode 100644 examples/test/semanticTests/viaYul_string_format/string_format_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_string_literals/string_literals.sol create mode 100644 examples/test/semanticTests/viaYul_string_literals/string_literals_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_struct_member_access/struct_member_access.sol create mode 100644 examples/test/semanticTests/viaYul_struct_member_access/struct_member_access_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order.sol create mode 100644 examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes.sol create mode 100644 examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_unary_operations/unary_operations.sol create mode 100644 examples/test/semanticTests/viaYul_unary_operations/unary_operations_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm.sol create mode 100644 examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm_standard_input.json create mode 100644 examples/test/semanticTests/viaYul_virtual_functions/virtual_functions.sol create mode 100644 examples/test/semanticTests/viaYul_virtual_functions/virtual_functions_standard_input.json create mode 100644 examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls.sol create mode 100644 examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls_standard_input.json create mode 100644 examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch.sol create mode 100644 examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch_standard_input.json create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls.sol create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls_standard_input.json create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments.sol create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments_standard_input.json create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal.sol create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal_standard_input.json create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public.sol create mode 100644 examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public_standard_input.json diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array.sol new file mode 100644 index 00000000..4d6b9207 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes calldata data) external pure returns (uint256[] memory) { + return abi.decode(data, (uint256[])); + } +} +// ---- +// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array_standard_input.json new file mode 100644 index 00000000..632f72d6 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_dynamic_array/abi_decode_dynamic_array_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays.sol new file mode 100644 index 00000000..2624591a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k) + public pure returns (uint, uint) { + return (a[i], b[j][k]); + } +} +// ---- +// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays_standard_input.json new file mode 100644 index 00000000..c2400093 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_fixed_arrays/abi_decode_fixed_arrays_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array.sol new file mode 100644 index 00000000..fd0a59ab --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array.sol @@ -0,0 +1,11 @@ +contract C { + function f(bytes calldata data) + external + pure + returns (uint256[2][3] memory) + { + return abi.decode(data, (uint256[2][3])); + } +} +// ---- +// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array_standard_input.json new file mode 100644 index 00000000..488cdbe2 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array/abi_decode_static_array_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2.sol new file mode 100644 index 00000000..e228099c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + + +contract C { + function f(bytes calldata data) + external + pure + returns (uint256[2][3] memory) + { + return abi.decode(data, (uint256[2][3])); + } +} +// ---- +// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2_standard_input.json new file mode 100644 index 00000000..d6dc24e7 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_static_array_v2/abi_decode_static_array_v2_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial.sol new file mode 100644 index 00000000..c1b91815 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes memory data) public pure returns (uint256) { + return abi.decode(data, (uint256)); + } +} +// ---- +// f(bytes): 0x20, 0x20, 0x21 -> 33 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial_standard_input.json new file mode 100644 index 00000000..c5c7518a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_trivial/abi_decode_trivial_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2.sol new file mode 100644 index 00000000..782971c5 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256[] b; + } + + function f() public pure returns (S memory) { + S memory s; + s.a = 8; + s.b = new uint256[](3); + s.b[0] = 9; + s.b[1] = 10; + s.b[2] = 11; + return abi.decode(abi.encode(s), (S)); + } +} +// ---- +// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2_standard_input.json new file mode 100644 index 00000000..cfa26574 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2/abi_decode_v2_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + }, + "abi_encode.sol": { + "content": "contract C {\n function f0() public returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n function f4() public returns (bytes memory) {\n bytes4 x = \"abcd\";\n return abi.encode(bytes2(x));\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n" + }, + "abi_decode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n return abi.decode(abi.encode(s), (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata.sol new file mode 100644 index 00000000..8bbb77b9 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256[] b; + } + + function f(bytes calldata data) external pure returns (S memory) { + return abi.decode(data, (S)); + } +} +// ---- +// f(bytes): 0x20, 0xe0, 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc -> 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata_standard_input.json new file mode 100644 index 00000000..5c3ce65d --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_calldata/abi_decode_v2_calldata_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + }, + "abi_encode.sol": { + "content": "contract C {\n function f0() public returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n function f4() public returns (bytes memory) {\n bytes4 x = \"abcd\";\n return abi.encode(bytes2(x));\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n" + }, + "abi_decode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n return abi.decode(abi.encode(s), (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n" + }, + "calldata_bytes_bytes32_arrays.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(bool a, bytes calldata b, bytes32[2] calldata c)\n public\n returns (bool, bytes calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bool,bytes,bytes32[2]): true, 0x80, \"a\", \"b\", 4, \"abcd\" -> true, 0x80, \"a\", \"b\", 4, \"abcd\"\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "abi_decode_v2_calldata.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f(bytes calldata data) external pure returns (S memory) {\n return abi.decode(data, (S));\n }\n}\n// ----\n// f(bytes): 0x20, 0xe0, 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc -> 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage.sol b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage.sol new file mode 100644 index 00000000..5c3bcba9 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage.sol @@ -0,0 +1,26 @@ +pragma abicoder v2; + + +contract C { + bytes data; + struct S { + uint256 a; + uint256[] b; + } + + function f() public returns (S memory) { + S memory s; + s.a = 8; + s.b = new uint256[](3); + s.b[0] = 9; + s.b[1] = 10; + s.b[2] = 11; + data = abi.encode(s); + return abi.decode(data, (S)); + } +} +// ---- +// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb +// gas irOptimized: 203167 +// gas legacy: 206263 +// gas legacyOptimized: 203172 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage_standard_input.json new file mode 100644 index 00000000..8be0c792 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_decode_v2_storage/abi_decode_v2_storage_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode.sol b/examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode.sol new file mode 100644 index 00000000..1e654d28 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode.sol @@ -0,0 +1,35 @@ +contract C { + function f0() public returns (bytes memory) { + return abi.encode(); + } + + function f1() public returns (bytes memory) { + return abi.encode(1, 2); + } + + function f2() public returns (bytes memory) { + string memory x = "abc"; + return abi.encode(1, x, 2); + } + + function f3() public returns (bytes memory r) { + // test that memory is properly allocated + string memory x = "abc"; + r = abi.encode(1, x, 2); + bytes memory y = "def"; + require(y[0] == "d"); + y[0] = "e"; + require(y[0] == "e"); + } + + function f4() public returns (bytes memory) { + bytes4 x = "abcd"; + return abi.encode(bytes2(x)); + } +} +// ---- +// f0() -> 0x20, 0x0 +// f1() -> 0x20, 0x40, 0x1, 0x2 +// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" +// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" +// f4() -> 0x20, 0x20, "ab" diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode_standard_input.json new file mode 100644 index 00000000..a71af72e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode/abi_encode_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + }, + "abi_encode.sol": { + "content": "contract C {\n function f0() public returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n function f4() public returns (bytes memory) {\n bytes4 x = \"abcd\";\n return abi.encode(bytes2(x));\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call.sol b/examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call.sol new file mode 100644 index 00000000..e34d46b7 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call.sol @@ -0,0 +1,25 @@ +contract C { + bool x; + + function c(uint256 a, uint256[] memory b) public { + require(a == 5); + require(b.length == 2); + require(b[0] == 6); + require(b[1] == 7); + x = true; + } + + function f() public returns (bool) { + uint256 a = 5; + uint256[] memory b = new uint256[](2); + b[0] = 6; + b[1] = 7; + (bool success, ) = address(this).call( + abi.encodeWithSignature("c(uint256,uint256[])", a, b) + ); + require(success); + return x; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call_standard_input.json new file mode 100644 index 00000000..301da350 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_call/abi_encode_call_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice.sol b/examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice.sol new file mode 100644 index 00000000..a6a4f8fd --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice.sol @@ -0,0 +1,68 @@ +contract C { + function enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(data[start:end]); + } + function enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(bytes(data[start:end])); + } + + function enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(data[start:end]); + } + function enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(bytes(data[start:end])); + } + + function enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(x[start:end]); + } + function enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(x[start:end]); + } + + function enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(x[start:end]); + } + function enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(x[start:end]); + } + + function compare(bytes memory x, bytes memory y) internal { + assert(x.length == y.length); + for (uint i = 0; i < x.length; ++i) + assert(x[i] == y[i]); + } + + function test_bytes() public { + bytes memory test = new bytes(3); + test[0] = 0x41; test[1] = 0x42; test[2] = 0x42; + for (uint i = 0; i < test.length; i++) + for (uint j = i; j <= test.length; j++) + { + compare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j)); + compare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j)); + } + } + + function test_uint256() public { + uint256[] memory test = new uint256[](3); + test[0] = 0x41; test[1] = 0x42; test[2] = 0x42; + for (uint i = 0; i < test.length; i++) + for (uint j = i; j <= test.length; j++) + { + compare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j)); + compare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j)); + } + } +} +// ==== +// EVMVersion: >homestead +// ---- +// test_bytes() -> +// gas irOptimized: 314884 +// gas legacy: 305816 +// gas legacyOptimized: 253573 +// test_uint256() -> +// gas irOptimized: 448346 +// gas legacy: 421304 +// gas legacyOptimized: 351544 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json new file mode 100644 index 00000000..53278a9f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + }, + "abi_encode.sol": { + "content": "contract C {\n function f0() public returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n function f4() public returns (bytes memory) {\n bytes4 x = \"abcd\";\n return abi.encode(bytes2(x));\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n" + }, + "abi_decode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n return abi.decode(abi.encode(s), (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n" + }, + "calldata_bytes_bytes32_arrays.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(bool a, bytes calldata b, bytes32[2] calldata c)\n public\n returns (bool, bytes calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bool,bytes,bytes32[2]): true, 0x80, \"a\", \"b\", 4, \"abcd\" -> true, 0x80, \"a\", \"b\", 4, \"abcd\"\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "abi_decode_v2_calldata.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f(bytes calldata data) external pure returns (S memory) {\n return abi.decode(data, (S));\n }\n}\n// ----\n// f(bytes): 0x20, 0xe0, 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc -> 0x20, 0x21, 0x40, 0x3, 0xa, 0xb, 0xc\n" + }, + "abi_encode_calldata_slice.sol": { + "content": "contract C {\n\tfunction enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(data[start:end]);\n\t}\n\tfunction enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(bytes(data[start:end]));\n\t}\n\n\tfunction enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(data[start:end]);\n\t}\n\tfunction enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[start:end]));\n\t}\n\n\tfunction enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\tfunction enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\n\tfunction enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\tfunction enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\n\tfunction compare(bytes memory x, bytes memory y) internal {\n\t\tassert(x.length == y.length);\n\t\tfor (uint i = 0; i < x.length; ++i)\n\t\t\tassert(x[i] == y[i]);\n\t}\n\n\tfunction test_bytes() public {\n\t\tbytes memory test = new bytes(3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j));\n\t\t\t\tcompare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j));\n\t\t\t}\n\t}\n\n\tfunction test_uint256() public {\n\t\tuint256[] memory test = new uint256[](3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j));\n\t\t\t\tcompare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j));\n\t\t\t}\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test_bytes() ->\n// gas irOptimized: 314884\n// gas legacy: 305816\n// gas legacyOptimized: 253573\n// test_uint256() ->\n// gas irOptimized: 448346\n// gas legacy: 421304\n// gas legacyOptimized: 351544\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple.sol b/examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple.sol new file mode 100644 index 00000000..627f0b0c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure returns (uint256, bytes memory) { + bytes memory arg = "abcdefg"; + return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes)); + } +} +// ---- +// f() -> 0x21, 0x40, 0x7, "abcdefg" diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple_standard_input.json new file mode 100644 index 00000000..f4779935 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_decode_simple/abi_encode_decode_simple_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string.sol b/examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string.sol new file mode 100644 index 00000000..601fb3cb --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string.sol @@ -0,0 +1,34 @@ +pragma abicoder v1; +contract C { + function f1() public returns (bytes memory) { + return abi.encode(""); + } + function f2(string calldata msg) public returns (bytes memory) { + return abi.encode(msg); + } + function g1() public returns (bytes memory) { + return abi.encodePacked(""); + } + function g2(string calldata msg) public returns (bytes memory) { + return abi.encodePacked(msg); + } + function h1() public returns (bytes memory) { + return abi.encodeWithSelector(0x00000001, ""); + } + function h2(string calldata msg) public returns (bytes memory) { + return abi.encodeWithSelector(0x00000001, msg); + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f1() -> 0x20, 0x40, 0x20, 0 +// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0 +// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0 +// g1() -> 32, 0 +// g2(string): 0x20, 0 -> 0x20, 0 +// g2(string): 0x20, 0, 0 -> 0x20, 0 +// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string_standard_input.json new file mode 100644 index 00000000..d6748e31 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_empty_string/abi_encode_empty_string_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational.sol b/examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational.sol new file mode 100644 index 00000000..44cf1ab5 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational.sol @@ -0,0 +1,8 @@ +// Tests that rational numbers (even negative ones) are encoded properly. +contract C { + function f() public pure returns (bytes memory) { + return abi.encode(1, -2); + } +} +// ---- +// f() -> 0x20, 0x40, 0x1, -2 diff --git a/examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational_standard_input.json b/examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational_standard_input.json new file mode 100644 index 00000000..a01f1b0a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_abi_encode_rational/abi_encode_rational_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds.sol b/examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds.sol new file mode 100644 index 00000000..d9b94ac2 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds.sol @@ -0,0 +1,12 @@ +pragma abicoder v1; +contract C { + function f(bool b) public pure returns (bool) { return b; } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(bool): true -> true +// f(bool): false -> false +// f(bool): 0x000000 -> false +// f(bool): 0xffffff -> true \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds_standard_input.json b/examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds_standard_input.json new file mode 100644 index 00000000..667f30e9 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_bool_out_of_bounds/bool_out_of_bounds_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays.sol b/examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays.sol new file mode 100644 index 00000000..9895c666 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays.sol @@ -0,0 +1,14 @@ +contract C { + function f(uint a, bytes memory b, uint c) + public pure returns (uint, uint, bytes1, uint) { + return (a, b.length, b[3], c); + } + + function f_external(uint a, bytes calldata b, uint c) + external pure returns (uint, uint, bytes1, uint) { + return (a, b.length, b[3], c); + } +} +// ---- +// f(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9 +// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9 diff --git a/examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays_standard_input.json new file mode 100644 index 00000000..1643aae4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_byte_arrays/byte_arrays_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large.sol b/examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large.sol new file mode 100644 index 00000000..49bee94e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large.sol @@ -0,0 +1,7 @@ +contract C { + function f(uint a, uint[] calldata b, uint c) external pure returns (uint) { + return 7; + } +} +// ---- +// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json b/examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json new file mode 100644 index 00000000..8fe1df70 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays.sol b/examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays.sol new file mode 100644 index 00000000..18a4ee1a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays.sol @@ -0,0 +1,14 @@ +pragma abicoder v1; + +contract C { + function f(bool a, bytes calldata b, bytes32[2] calldata c) + public + returns (bool, bytes calldata, bytes32[2] calldata) + { + return (a, b, c); + } +} +// ==== +// compileViaYul: false +// ---- +// f(bool,bytes,bytes32[2]): true, 0x80, "a", "b", 4, "abcd" -> true, 0x80, "a", "b", 4, "abcd" diff --git a/examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays_standard_input.json new file mode 100644 index 00000000..b2844688 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_calldata_bytes_bytes32_arrays/calldata_bytes_bytes32_arrays_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + }, + "abi_encode.sol": { + "content": "contract C {\n function f0() public returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n function f4() public returns (bytes memory) {\n bytes4 x = \"abcd\";\n return abi.encode(bytes2(x));\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n" + }, + "abi_decode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n return abi.decode(abi.encode(s), (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n" + }, + "calldata_bytes_bytes32_arrays.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(bool a, bytes calldata b, bytes32[2] calldata c)\n public\n returns (bool, bytes calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bool,bytes,bytes32[2]): true, 0x80, \"a\", \"b\", 4, \"abcd\" -> true, 0x80, \"a\", \"b\", 4, \"abcd\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup.sol b/examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup.sol new file mode 100644 index 00000000..262c4412 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup.sol @@ -0,0 +1,18 @@ +pragma abicoder v1; +contract C { + function f(uint16 a, int16 b, address c, bytes3 d, bool e) + public pure returns (uint v, uint w, uint x, uint y, uint z) { + assembly { v := a w := b x := c y := d z := e} + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(uint16,int16,address,bytes3,bool): 1, 2, 3, "a", true -> 1, 2, 3, "a", true +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "abcd", 1 -> 0xffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffff, "abc", true +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, "bcd", 1 -> 0xffff, 0, 0, "bcd", true +// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, "ab", 1 -> 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0, "ab", true +// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "ad", 1 -> 0, 0, 0xffffffffffffffffffffffffffffffffffffffff, "ad", true +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abcd", 1 -> 0, 0, 0, "abc", true +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abc", 2 -> 0, 0, 0, "abc", true diff --git a/examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup_standard_input.json b/examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup_standard_input.json new file mode 100644 index 00000000..477c644e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_cleanup_cleanup/cleanup_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "cleanup.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> 0xffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffff, \"abc\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> 0xffff, 0, 0, \"bcd\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0, \"ab\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> 0, 0, 0xffffffffffffffffffffffffffffffffffffffff, \"ad\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> 0, 0, 0, \"abc\", true\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> 0, 0, 0, \"abc\", true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice.sol b/examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice.sol new file mode 100644 index 00000000..35cb1507 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice.sol @@ -0,0 +1,9 @@ +contract C { + function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) { + (c, d) = abi.decode(msg.data[4:], (uint256, uint256)); + e = abi.decode(msg.data[4 : 4 + 32], (uint256)); + f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256)); + } +} +// ---- +// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23 diff --git a/examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice_standard_input.json b/examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice_standard_input.json new file mode 100644 index 00000000..f4213b69 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_decode_slice/decode_slice_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays.sol b/examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays.sol new file mode 100644 index 00000000..7eb9a388 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint a, uint16[] memory b, uint c) + public pure returns (uint, uint, uint) { + return (b.length, b[a], c); + } +} +// ---- +// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9 diff --git a/examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays_standard_input.json new file mode 100644 index 00000000..193098a3 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_dynamic_arrays/dynamic_arrays_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy.sol b/examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy.sol new file mode 100644 index 00000000..ef2b07cb --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy.sol @@ -0,0 +1,26 @@ +contract C { + function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) { + (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[])); + assembly { + // Check whether arr1 and arr2 end up at the same memory location. + // This used to be the case, if both tail pointers in buf pointed to the + // same memory region, i.e. this used to be false in the first two, but true + // in the last three calls below. The desired behaviour is to always get distinct + // memory regions, i.e. this should be false. + same := eq(arr1, arr2) + // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below) + // arr1 points to the part of buf containing the encoding of arr1. + // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer) + // of buf. + // This used to be the case for all the test calls below, whereas now arr1 is always copied + // from buf to a new memory area. Should always be false. + inplaceDecoded := eq(arr1, add(buf, 0x60)) + } + } +} +// ---- +// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false +// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false +// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false +// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false +// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false diff --git a/examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy_standard_input.json b/examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy_standard_input.json new file mode 100644 index 00000000..12555afe --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_dynamic_memory_copy/dynamic_memory_copy_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_enums/enums.sol b/examples/test/semanticTests/abiEncoderV1_enums/enums.sol new file mode 100644 index 00000000..a51aaebd --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_enums/enums.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +contract C { + enum E { A, B } + function f(E e) public pure returns (uint x) { + assembly { x := e } + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(uint8): 0 -> 0 +// f(uint8): 1 -> 1 +// f(uint8): 2 -> 2 +// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff diff --git a/examples/test/semanticTests/abiEncoderV1_enums/enums_standard_input.json b/examples/test/semanticTests/abiEncoderV1_enums/enums_standard_input.json new file mode 100644 index 00000000..54fcbfe5 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_enums/enums_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol b/examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol new file mode 100644 index 00000000..f828ab41 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol @@ -0,0 +1,16 @@ +pragma abicoder v1; + +contract C { + function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) { + return f(a, b); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, "123456" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, "123456" +// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, "12345678" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, "12345678" diff --git a/examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json b/examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json new file mode 100644 index 00000000..58a182c8 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + }, + "abi_decode_static_array_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "decode_slice.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) {\n (c, d) = abi.decode(msg.data[4:], (uint256, uint256));\n e = abi.decode(msg.data[4 : 4 + 32], (uint256));\n f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256));\n }\n}\n// ----\n// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23\n" + }, + "calldata_arrays_too_large.sol": { + "content": "contract C {\n function f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n return 7;\n }\n}\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x8000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE\n" + }, + "abi_decode_static_array.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256[2][3] memory)\n {\n return abi.decode(data, (uint256[2][3]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 -> 1, 2, 3, 4, 5, 6\n" + }, + "dynamic_memory_copy.sol": { + "content": "contract C {\n function test(bytes memory buf) public view returns (bool same, bool inplaceDecoded) {\n (uint256[] memory arr1, uint256[] memory arr2) = abi.decode(buf, (uint256[],uint256[]));\n assembly {\n // Check whether arr1 and arr2 end up at the same memory location.\n // This used to be the case, if both tail pointers in buf pointed to the\n // same memory region, i.e. this used to be false in the first two, but true\n // in the last three calls below. The desired behaviour is to always get distinct\n // memory regions, i.e. this should be false.\n same := eq(arr1, arr2)\n // Check whether (given the particular tail pointer of 0x40 for arr1 in the calls below)\n // arr1 points to the part of buf containing the encoding of arr1.\n // The position of the encoding of arr1 in buf is at offset 0x20 (length) + 0x40 (tail pointer)\n // of buf.\n // This used to be the case for all the test calls below, whereas now arr1 is always copied\n // from buf to a new memory area. Should always be false.\n inplaceDecoded := eq(arr1, add(buf, 0x60))\n }\n }\n}\n// ----\n// test(bytes): 0x20, 0x80, 0x40, 0x60, 0, 0 -> false, false\n// test(bytes): 0x20, 0xC0, 0x40, 0x80, 1, 0x42, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n// test(bytes): 0x20, 0x60, 0x40, 0x40, 0 -> false, false\n// test(bytes): 0x20, 0x80, 0x40, 0x40, 1, 0x42 -> false, false\n" + }, + "abi_encode_call.sol": { + "content": "contract C {\n bool x;\n\n function c(uint256 a, uint256[] memory b) public {\n require(a == 5);\n require(b.length == 2);\n require(b[0] == 6);\n require(b[1] == 7);\n x = true;\n }\n\n function f() public returns (bool) {\n uint256 a = 5;\n uint256[] memory b = new uint256[](2);\n b[0] = 6;\n b[1] = 7;\n (bool success, ) = address(this).call(\n abi.encodeWithSignature(\"c(uint256,uint256[])\", a, b)\n );\n require(success);\n return x;\n }\n}\n// ----\n// f() -> true\n" + }, + "abi_decode_fixed_arrays.sol": { + "content": "contract C {\n function f(uint16[3] memory a, uint16[2][3] memory b, uint i, uint j, uint k)\n public pure returns (uint, uint) {\n return (a[i], b[j][k]);\n }\n}\n// ----\n// f(uint16[3],uint16[2][3],uint256,uint256,uint256): 1, 2, 3, 11, 12, 21, 22, 31, 32, 1, 2, 1 -> 2, 32\n" + }, + "abi_encode.sol": { + "content": "contract C {\n function f0() public returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n function f4() public returns (bytes memory) {\n bytes4 x = \"abcd\";\n return abi.encode(bytes2(x));\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x20, \"ab\"\n" + }, + "abi_decode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n return abi.decode(abi.encode(s), (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n" + }, + "calldata_bytes_bytes32_arrays.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(bool a, bytes calldata b, bytes32[2] calldata c)\n public\n returns (bool, bytes calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bool,bytes,bytes32[2]): true, 0x80, \"a\", \"b\", 4, \"abcd\" -> true, 0x80, \"a\", \"b\", 4, \"abcd\"\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "pragma abicoder v1;\n\ncontract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function.sol b/examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function.sol new file mode 100644 index 00000000..dbabfc35 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function.sol @@ -0,0 +1,16 @@ +contract C { + function f(bytes memory a, bytes calldata b, uint[] memory c) + external + pure + returns (uint, bytes1, uint, bytes1, uint, uint) + { + return (a.length, a[1], b.length, b[2], c.length, c[3]); + } + function g() public returns (uint, bytes1, uint, bytes1, uint, uint) { + uint[] memory x = new uint[](4); + x[3] = 7; + return this.f("abc", "def", x); + } +} +// ---- +// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7 diff --git a/examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function_standard_input.json b/examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function_standard_input.json new file mode 100644 index 00000000..4e468af4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_memory_params_in_external_function/memory_params_in_external_function_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced.sol b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced.sol new file mode 100644 index 00000000..24c1b232 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced.sol @@ -0,0 +1,17 @@ +contract C { + function dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) { + a = "1234567890123456789012345678901234567890"; + b = type(uint).max; + c = new bytes20[](4); + c[0] = bytes20(uint160(1234)); + c[3] = bytes20(uint160(6789)); + d = 0x1234; + } + function f() public returns (bytes memory, uint, bytes20[] memory, uint) { + return this.dyn(); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f() -> 0x80, -1, 0xe0, 0x1234, 40, "12345678901234567890123456789012", "34567890", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104 diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced_standard_input.json b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced_standard_input.json new file mode 100644 index 00000000..f8034f42 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_advanced/return_dynamic_types_cross_call_advanced_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + }, + "abi_decode_trivial.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256) {\n return abi.decode(data, (uint256));\n }\n}\n// ----\n// f(bytes): 0x20, 0x20, 0x21 -> 33\n" + }, + "abi_encode_empty_string.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f1() public returns (bytes memory) {\n return abi.encode(\"\");\n }\n function f2(string calldata msg) public returns (bytes memory) {\n return abi.encode(msg);\n }\n function g1() public returns (bytes memory) {\n return abi.encodePacked(\"\");\n }\n function g2(string calldata msg) public returns (bytes memory) {\n return abi.encodePacked(msg);\n }\n function h1() public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, \"\");\n }\n function h2(string calldata msg) public returns (bytes memory) {\n return abi.encodeWithSelector(0x00000001, msg);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f1() -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0 -> 0x20, 0x40, 0x20, 0\n// f2(string): 0x20, 0, 0 -> 0x20, 0x40, 0x20, 0\n// g1() -> 32, 0\n// g2(string): 0x20, 0 -> 0x20, 0\n// g2(string): 0x20, 0, 0 -> 0x20, 0\n// h1() -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// h2(string): 0x20, 0, 0 -> 0x20, 0x44, 26959946667150639794667015087019630673637144422540572481103610249216, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n" + }, + "enums.sol": { + "content": "pragma abicoder v1;\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> 2\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff\n" + }, + "abi_decode_v2_storage.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n bytes data;\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f() public returns (S memory) {\n S memory s;\n s.a = 8;\n s.b = new uint256[](3);\n s.b[0] = 9;\n s.b[1] = 10;\n s.b[2] = 11;\n data = abi.encode(s);\n return abi.decode(data, (S));\n }\n}\n// ----\n// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb\n// gas irOptimized: 203167\n// gas legacy: 206263\n// gas legacyOptimized: 203172\n" + }, + "return_dynamic_types_cross_call_advanced.sol": { + "content": "contract C {\n\tfunction dyn() public returns (bytes memory a, uint b, bytes20[] memory c, uint d) {\n\t\ta = \"1234567890123456789012345678901234567890\";\n\t\tb = type(uint).max;\n\t\tc = new bytes20[](4);\n\t\tc[0] = bytes20(uint160(1234));\n\t\tc[3] = bytes20(uint160(6789));\n\t\td = 0x1234;\n\t}\n\tfunction f() public returns (bytes memory, uint, bytes20[] memory, uint) {\n\t\treturn this.dyn();\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x80, -1, 0xe0, 0x1234, 40, \"12345678901234567890123456789012\", \"34567890\", 4, 97767552542602192590433234714624, 0, 0, 537879995309340587922569878831104\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1.sol b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1.sol new file mode 100644 index 00000000..191b4e6b --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1.sol @@ -0,0 +1,19 @@ +contract C { + function dyn(uint x) public returns (bytes memory a) { + assembly { + mstore(0, 0x20) + mstore(0x20, 0x21) + return(0, x) + } + } + function f(uint x) public returns (bool) { + this.dyn(x); + return true; + } +} +// ==== +// EVMVersion: =homestead +// ---- +// f(uint256): 0x60 -> true +// f(uint256): 0x7f -> true +// f(uint256): 0x80 -> true \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1_standard_input.json b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1_standard_input.json new file mode 100644 index 00000000..e844b5db --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_1/return_dynamic_types_cross_call_out_of_range_1_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2.sol b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2.sol new file mode 100644 index 00000000..cfbd0032 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2.sol @@ -0,0 +1,19 @@ +contract C { + function dyn(uint x) public returns (bytes memory a) { + assembly { + mstore(0, 0x20) + mstore(0x20, 0x21) + return(0, x) + } + } + function f(uint x) public returns (bool) { + this.dyn(x); + return true; + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256): 0x60 -> FAILURE +// f(uint256): 0x61 -> true +// f(uint256): 0x80 -> true diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2_standard_input.json b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2_standard_input.json new file mode 100644 index 00000000..9a164550 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_out_of_range_2/return_dynamic_types_cross_call_out_of_range_2_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple.sol b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple.sol new file mode 100644 index 00000000..bd12b0a9 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple.sol @@ -0,0 +1,12 @@ +contract C { + function dyn() public returns (bytes memory) { + return "1234567890123456789012345678901234567890"; + } + function f() public returns (bytes memory) { + return this.dyn(); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f() -> 0x20, 40, "12345678901234567890123456789012", "34567890" diff --git a/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple_standard_input.json b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple_standard_input.json new file mode 100644 index 00000000..efe80129 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_return_dynamic_types_cross_call_simple/return_dynamic_types_cross_call_simple_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "abi_decode_dynamic_array.sol": { + "content": "contract C {\n function f(bytes calldata data) external pure returns (uint256[] memory) {\n return abi.decode(data, (uint256[]));\n }\n}\n// ----\n// f(bytes): 0x20, 0xc0, 0x20, 0x4, 0x3, 0x4, 0x5, 0x6 -> 0x20, 0x4, 0x3, 0x4, 0x5, 0x6\n" + }, + "return_dynamic_types_cross_call_out_of_range_2.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256): 0x60 -> FAILURE\n// f(uint256): 0x61 -> true\n// f(uint256): 0x80 -> true\n" + }, + "dynamic_arrays.sol": { + "content": "contract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "byte_arrays.sol": { + "content": "contract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "return_dynamic_types_cross_call_out_of_range_1.sol": { + "content": "contract C {\n function dyn(uint x) public returns (bytes memory a) {\n assembly {\n mstore(0, 0x20)\n mstore(0x20, 0x21)\n return(0, x)\n }\n }\n function f(uint x) public returns (bool) {\n this.dyn(x);\n return true;\n }\n}\n// ====\n// EVMVersion: =homestead\n// ----\n// f(uint256): 0x60 -> true\n// f(uint256): 0x7f -> true\n// f(uint256): 0x80 -> true" + }, + "abi_encode_decode_simple.sol": { + "content": "contract C {\n function f() public pure returns (uint256, bytes memory) {\n bytes memory arg = \"abcdefg\";\n return abi.decode(abi.encode(uint256(33), arg), (uint256, bytes));\n }\n}\n// ----\n// f() -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_rational.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "memory_params_in_external_function.sol": { + "content": "contract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> true" + }, + "return_dynamic_types_cross_call_simple.sol": { + "content": "contract C {\n function dyn() public returns (bytes memory) {\n return \"1234567890123456789012345678901234567890\";\n }\n function f() public returns (bytes memory) {\n return this.dyn();\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 40, \"12345678901234567890123456789012\", \"34567890\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr.sol b/examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr.sol new file mode 100644 index 00000000..ed983c77 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr.sol @@ -0,0 +1,29 @@ +library L { + struct S { uint x; uint y; } + function f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) { + r[2] = 8; + s.x = 7; + return (r[0], r[1], s.x, s.y); + } +} +contract C { + uint8 x = 3; + L.S s; + uint[] r; + function f() public returns (uint, uint, uint, uint, uint, uint) { + r = new uint[](6); + r[0] = 1; + r[1] = 2; + r[2] = 3; + s.x = 11; + s.y = 12; + (uint a, uint b, uint c, uint d) = L.f(r, s); + return (r[2], s.x, a, b, c, d); + } +} +// ---- +// library: L +// f() -> 8, 7, 1, 2, 7, 12 +// gas irOptimized: 166761 +// gas legacy: 169273 +// gas legacyOptimized: 167243 diff --git a/examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr_standard_input.json b/examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr_standard_input.json new file mode 100644 index 00000000..b144584d --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV1_struct_struct_storage_ptr/struct_storage_ptr_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "struct_storage_ptr.sol": { + "content": "library L {\n\tstruct S { uint x; uint y; }\n\tfunction f(uint[] storage r, S storage s) public returns (uint, uint, uint, uint) {\n\t\tr[2] = 8;\n\t\ts.x = 7;\n\t\treturn (r[0], r[1], s.x, s.y);\n\t}\n}\ncontract C {\n\tuint8 x = 3;\n\tL.S s;\n\tuint[] r;\n\tfunction f() public returns (uint, uint, uint, uint, uint, uint) {\n\t\tr = new uint[](6);\n\t\tr[0] = 1;\n\t\tr[1] = 2;\n\t\tr[2] = 3;\n\t\ts.x = 11;\n\t\ts.y = 12;\n\t\t(uint a, uint b, uint c, uint d) = L.f(r, s);\n\t\treturn (r[2], s.x, a, b, c, d);\n\t}\n}\n// ----\n// library: L\n// f() -> 8, 7, 1, 2, 7, 12\n// gas irOptimized: 166761\n// gas legacy: 169273\n// gas legacyOptimized: 167243\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice.sol b/examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice.sol new file mode 100644 index 00000000..0c59c33c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice.sol @@ -0,0 +1,69 @@ +pragma abicoder v2; +contract C { + function enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(data[start:end]); + } + function enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(bytes(data[start:end])); + } + + function enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(data[start:end]); + } + function enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(bytes(data[start:end])); + } + + function enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(x[start:end]); + } + function enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encode(x[start:end]); + } + + function enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(x[start:end]); + } + function enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) { + return abi.encodePacked(x[start:end]); + } + + function compare(bytes memory x, bytes memory y) internal { + assert(x.length == y.length); + for (uint i = 0; i < x.length; ++i) + assert(x[i] == y[i]); + } + + function test_bytes() public { + bytes memory test = new bytes(3); + test[0] = 0x41; test[1] = 0x42; test[2] = 0x42; + for (uint i = 0; i < test.length; i++) + for (uint j = i; j <= test.length; j++) + { + compare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j)); + compare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j)); + } + } + + function test_uint256() public { + uint256[] memory test = new uint256[](3); + test[0] = 0x41; test[1] = 0x42; test[2] = 0x42; + for (uint i = 0; i < test.length; i++) + for (uint j = i; j <= test.length; j++) + { + compare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j)); + compare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j)); + } + } +} +// ==== +// EVMVersion: >homestead +// ---- +// test_bytes() -> +// gas irOptimized: 314884 +// gas legacy: 305816 +// gas legacyOptimized: 253573 +// test_uint256() -> +// gas irOptimized: 448346 +// gas legacy: 421304 +// gas legacyOptimized: 351544 diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json new file mode 100644 index 00000000..a44d2500 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_calldata_slice/abi_encode_calldata_slice_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + }, + "calldata_nested_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function g(uint8[][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function h(uint16[][2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function i(uint16[][][1] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function j(uint16[2][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n" + }, + "abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol": { + "content": "pragma abicoder v2;\n\nstruct T {\n bytes x;\n uint[3] y;\n}\n\ncontract E {\n function f(bool a, T calldata b, bytes32[2] calldata c)\n public\n returns (bool, T calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ----\n// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\" -> 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE\n" + }, + "abi_encode_calldata_slice.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(data[start:end]);\n\t}\n\tfunction enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(bytes(data[start:end]));\n\t}\n\n\tfunction enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(data[start:end]);\n\t}\n\tfunction enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[start:end]));\n\t}\n\n\tfunction enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\tfunction enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\n\tfunction enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\tfunction enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\n\tfunction compare(bytes memory x, bytes memory y) internal {\n\t\tassert(x.length == y.length);\n\t\tfor (uint i = 0; i < x.length; ++i)\n\t\t\tassert(x[i] == y[i]);\n\t}\n\n\tfunction test_bytes() public {\n\t\tbytes memory test = new bytes(3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j));\n\t\t\t\tcompare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j));\n\t\t\t}\n\t}\n\n\tfunction test_uint256() public {\n\t\tuint256[] memory test = new uint256[](3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j));\n\t\t\t\tcompare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j));\n\t\t\t}\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test_bytes() ->\n// gas irOptimized: 314884\n// gas legacy: 305816\n// gas legacyOptimized: 253573\n// test_uint256() ->\n// gas irOptimized: 448346\n// gas legacy: 421304\n// gas legacyOptimized: 351544\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2.sol b/examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2.sol new file mode 100644 index 00000000..849c24a9 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2.sol @@ -0,0 +1,12 @@ +// Tests that this will not end up using a "bytes0" type +// (which would assert) +pragma abicoder v2; + + +contract C { + function f() public pure returns (bytes memory, bytes memory) { + return (abi.encode(""), abi.encodePacked("")); + } +} +// ---- +// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0 diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2_standard_input.json new file mode 100644 index 00000000..09c43205 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_empty_string_v2/abi_encode_empty_string_v2_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + }, + "calldata_nested_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function g(uint8[][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function h(uint16[][2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function i(uint16[][][1] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function j(uint16[2][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n" + }, + "abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol": { + "content": "pragma abicoder v2;\n\nstruct T {\n bytes x;\n uint[3] y;\n}\n\ncontract E {\n function f(bool a, T calldata b, bytes32[2] calldata c)\n public\n returns (bool, T calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ----\n// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\" -> 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE\n" + }, + "abi_encode_calldata_slice.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(data[start:end]);\n\t}\n\tfunction enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(bytes(data[start:end]));\n\t}\n\n\tfunction enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(data[start:end]);\n\t}\n\tfunction enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[start:end]));\n\t}\n\n\tfunction enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\tfunction enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\n\tfunction enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\tfunction enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\n\tfunction compare(bytes memory x, bytes memory y) internal {\n\t\tassert(x.length == y.length);\n\t\tfor (uint i = 0; i < x.length; ++i)\n\t\t\tassert(x[i] == y[i]);\n\t}\n\n\tfunction test_bytes() public {\n\t\tbytes memory test = new bytes(3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j));\n\t\t\t\tcompare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j));\n\t\t\t}\n\t}\n\n\tfunction test_uint256() public {\n\t\tuint256[] memory test = new uint256[](3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j));\n\t\t\t\tcompare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j));\n\t\t\t}\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test_bytes() ->\n// gas irOptimized: 314884\n// gas legacy: 305816\n// gas legacyOptimized: 253573\n// test_uint256() ->\n// gas irOptimized: 448346\n// gas legacy: 421304\n// gas legacyOptimized: 351544\n" + }, + "abi_encode_v2_in_modifier_used_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint value;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5);\n }\n}\n\ncontract B {\n uint x = 10;\n uint y = 10;\n\n modifier updateStorage() {\n A a = new A();\n x = a.get().value;\n _;\n y = a.get().value;\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test()\n public\n updateStorage\n returns (uint, uint)\n {\n return (x, y);\n }\n}\n// ----\n// test() -> 5, 10\n// gas irOptimized: 87337\n// gas legacy: 66250\n// gas legacy code: 36400\n" + }, + "abi_encode_empty_string_v2.sol": { + "content": "// Tests that this will not end up using a \"bytes0\" type\n// (which would assert)\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory, bytes memory) {\n return (abi.encode(\"\"), abi.encodePacked(\"\"));\n }\n}\n// ----\n// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2.sol b/examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2.sol new file mode 100644 index 00000000..edd319d4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2.sol @@ -0,0 +1,11 @@ +// Tests that rational numbers (even negative ones) are encoded properly. +pragma abicoder v2; + + +contract C { + function f() public pure returns (bytes memory) { + return abi.encode(1, -2); + } +} +// ---- +// f() -> 0x20, 0x40, 0x1, -2 diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2_standard_input.json new file mode 100644 index 00000000..c6c9f33b --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_rational_v2/abi_encode_rational_v2_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2.sol b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2.sol new file mode 100644 index 00000000..edfe075d --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2.sol @@ -0,0 +1,55 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256[] b; + } + + function f0() public pure returns (bytes memory) { + return abi.encode(); + } + + function f1() public pure returns (bytes memory) { + return abi.encode(1, 2); + } + + function f2() public pure returns (bytes memory) { + string memory x = "abc"; + return abi.encode(1, x, 2); + } + + function f3() public pure returns (bytes memory r) { + // test that memory is properly allocated + string memory x = "abc"; + r = abi.encode(1, x, 2); + bytes memory y = "def"; + require(y[0] == "d"); + y[0] = "e"; + require(y[0] == "e"); + } + + S s; + + function f4() public returns (bytes memory r) { + string memory x = "abc"; + s.a = 7; + s.b.push(2); + s.b.push(3); + r = abi.encode(1, x, s, 2); + bytes memory y = "def"; + require(y[0] == "d"); + y[0] = "e"; + require(y[0] == "e"); + } +} +// ---- +// f0() -> 0x20, 0x0 +// f1() -> 0x20, 0x40, 0x1, 0x2 +// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" +// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" +// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3 +// gas irOptimized: 111816 +// gas legacy: 113890 +// gas legacyOptimized: 111658 diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2_standard_input.json new file mode 100644 index 00000000..b3faeccf --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2/abi_encode_v2_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract.sol new file mode 100644 index 00000000..bb3ad1aa --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -0,0 +1,38 @@ +==== Source: A ==== +pragma abicoder v2; + +struct Data { + uint a; + uint[2] b; + uint c; +} + +contract A { + function get() public view returns (Data memory) { + return Data(5, [uint(66), 77], 8); + } +} + +contract B { + function foo(A _a) public returns (uint) { + return _a.get().b[1]; + } +} +==== Source: B ==== +pragma abicoder v1; + +import "A"; + +contract C is B { + function test() public returns (uint) { + return foo(new A()); + } +} +// ---- +// test() -> 77 +// gas irOptimized: 55117 +// gas irOptimized code: 56800 +// gas legacy: 57266 +// gas legacy code: 94600 +// gas legacyOptimized: 55195 +// gas legacyOptimized code: 55000 diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract_standard_input.json new file mode 100644 index 00000000..9930720d --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_function_inherited_in_v1_contract/abi_encode_v2_in_function_inherited_in_v1_contract_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract.sol new file mode 100644 index 00000000..8df4090c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -0,0 +1,43 @@ +==== Source: A ==== +pragma abicoder v2; + +struct Data { + uint value; +} + +contract A { + function get() public view returns (Data memory) { + return Data(5); + } +} + +contract B { + uint x = 10; + uint y = 10; + + modifier updateStorage() { + A a = new A(); + x = a.get().value; + _; + y = a.get().value; + } +} +==== Source: B ==== +pragma abicoder v1; + +import "A"; + +contract C is B { + function test() + public + updateStorage + returns (uint, uint) + { + return (x, y); + } +} +// ---- +// test() -> 5, 10 +// gas irOptimized: 87337 +// gas legacy: 66250 +// gas legacy code: 36400 diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract_standard_input.json new file mode 100644 index 00000000..20b8a56f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encode_v2_in_modifier_used_in_v1_contract/abi_encode_v2_in_modifier_used_in_v1_contract_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + }, + "calldata_nested_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function g(uint8[][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function h(uint16[][2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function i(uint16[][][1] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function j(uint16[2][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n" + }, + "abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol": { + "content": "pragma abicoder v2;\n\nstruct T {\n bytes x;\n uint[3] y;\n}\n\ncontract E {\n function f(bool a, T calldata b, bytes32[2] calldata c)\n public\n returns (bool, T calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ----\n// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\" -> 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE\n" + }, + "abi_encode_calldata_slice.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction enc_packed_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(data[start:end]);\n\t}\n\tfunction enc_packed_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(bytes(data[start:end]));\n\t}\n\n\tfunction enc_bytes(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(data[start:end]);\n\t}\n\tfunction enc_bytes_reference(bytes calldata data, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(bytes(data[start:end]));\n\t}\n\n\tfunction enc_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\tfunction enc_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encode(x[start:end]);\n\t}\n\n\tfunction enc_packed_uint256(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\tfunction enc_packed_uint256_reference(uint256[] calldata x, uint256 start, uint256 end) external returns (bytes memory) {\n\t\treturn abi.encodePacked(x[start:end]);\n\t}\n\n\tfunction compare(bytes memory x, bytes memory y) internal {\n\t\tassert(x.length == y.length);\n\t\tfor (uint i = 0; i < x.length; ++i)\n\t\t\tassert(x[i] == y[i]);\n\t}\n\n\tfunction test_bytes() public {\n\t\tbytes memory test = new bytes(3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_bytes(test, i, j), this.enc_packed_bytes_reference(test, i, j));\n\t\t\t\tcompare(this.enc_bytes(test, i, j), this.enc_bytes_reference(test, i, j));\n\t\t\t}\n\t}\n\n\tfunction test_uint256() public {\n\t\tuint256[] memory test = new uint256[](3);\n\t\ttest[0] = 0x41; test[1] = 0x42; test[2] = 0x42;\n\t\tfor (uint i = 0; i < test.length; i++)\n\t\t\tfor (uint j = i; j <= test.length; j++)\n\t\t\t{\n\t\t\t\tcompare(this.enc_packed_uint256(test, i, j), this.enc_packed_uint256_reference(test, i, j));\n\t\t\t\tcompare(this.enc_uint256(test, i, j), this.enc_uint256_reference(test, i, j));\n\t\t\t}\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test_bytes() ->\n// gas irOptimized: 314884\n// gas legacy: 305816\n// gas legacyOptimized: 253573\n// test_uint256() ->\n// gas irOptimized: 448346\n// gas legacy: 421304\n// gas legacyOptimized: 351544\n" + }, + "abi_encode_v2_in_modifier_used_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint value;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5);\n }\n}\n\ncontract B {\n uint x = 10;\n uint y = 10;\n\n modifier updateStorage() {\n A a = new A();\n x = a.get().value;\n _;\n y = a.get().value;\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test()\n public\n updateStorage\n returns (uint, uint)\n {\n return (x, y);\n }\n}\n// ----\n// test() -> 5, 10\n// gas irOptimized: 87337\n// gas legacy: 66250\n// gas legacy code: 36400\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol b/examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol new file mode 100644 index 00000000..9e5d5755 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; + +struct T { + bytes x; + uint[3] y; +} + +contract E { + function f(bool a, T calldata b, bytes32[2] calldata c) + public + returns (bool, T calldata, bytes32[2] calldata) + { + return (a, b, c); + } +} +// ---- +// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, "a", "b", 0x80, 11, 12, 13, 4, "abcd" -> 1, 0x80, "a", "b", 0x80, 11, 12, 13, 4, "abcd" diff --git a/examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug_standard_input.json b/examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug_standard_input.json new file mode 100644 index 00000000..859ff9f9 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_abi_encoder_v2_head_overflow_with_static_array_cleanup_bug/abi_encoder_v2_head_overflow_with_static_array_cleanup_bug_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + }, + "calldata_nested_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function g(uint8[][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function h(uint16[][2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function i(uint16[][][1] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function j(uint16[2][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n" + }, + "abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol": { + "content": "pragma abicoder v2;\n\nstruct T {\n bytes x;\n uint[3] y;\n}\n\ncontract E {\n function f(bool a, T calldata b, bytes32[2] calldata c)\n public\n returns (bool, T calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ----\n// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\" -> 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds.sol b/examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds.sol new file mode 100644 index 00000000..e4712570 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds.sol @@ -0,0 +1,10 @@ +pragma abicoder v2; + +contract C { + function f(bool b) public pure returns (bool) { return b; } +} +// ---- +// f(bool): true -> true +// f(bool): false -> false +// f(bool): 0x000000 -> false +// f(bool): 0xffffff -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds_standard_input.json b/examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds_standard_input.json new file mode 100644 index 00000000..d6ad2d61 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_bool_out_of_bounds/bool_out_of_bounds_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays.sol b/examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays.sol new file mode 100644 index 00000000..078da3fd --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + function f(uint a, bytes memory b, uint c) + public pure returns (uint, uint, bytes1, uint) { + return (a, b.length, b[3], c); + } + + function f_external(uint a, bytes calldata b, uint c) + external pure returns (uint, uint, bytes1, uint) { + return (a, b.length, b[3], c); + } +} +// ---- +// f(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9 +// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9 diff --git a/examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays_standard_input.json new file mode 100644 index 00000000..8aa6f4ca --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_byte_arrays/byte_arrays_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array.sol new file mode 100644 index 00000000..cdce1b95 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + function g(uint256[] calldata) external pure returns (bytes memory) { + return msg.data; + } + function f(uint256[][1] calldata s) external view returns (bool) { + bytes memory a = this.g(s[0]); + uint256[] memory m = s[0]; + bytes memory b = this.g(m); + assert(a.length == b.length); + for (uint i = 0; i < a.length; i++) + assert(a[i] == b[i]); + return true; + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[][1]): 32, 32, 0 -> true +// f(uint256[][1]): 32, 32, 1, 42 -> true +// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true +// gas irOptimized: 120978 +// gas legacy: 101568 +// gas legacyOptimized: 119092 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array_standard_input.json new file mode 100644 index 00000000..8ff6d5fd --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array/calldata_array_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic.sol new file mode 100644 index 00000000..c1208218 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic.sol @@ -0,0 +1,33 @@ +pragma abicoder v2; + +contract C { + function f(uint256[] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function g(uint256[] calldata s) external view returns (bytes memory) { + return this.f(s); + } + function h(uint8[] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function i(uint8[] calldata s) external view returns (bytes memory) { + return this.h(s); + } + function j(bytes calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function k(bytes calldata s) external view returns (bytes memory) { + return this.j(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87 +// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87 +// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87 +// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87 +// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE +// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE +// j(bytes): 32, 3, hex"123456" -> 32, 96, 32, 3, left(0x123456) +// k(bytes): 32, 3, hex"AB33FF" -> 32, 96, 32, 3, left(0xAB33FF) diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic_standard_input.json new file mode 100644 index 00000000..36664062 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic/calldata_array_dynamic_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access.sol new file mode 100644 index 00000000..a9e3d8b1 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access.sol @@ -0,0 +1,34 @@ +pragma abicoder v2; + +contract C { + function f(uint256[] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) { + return this.f(s[which]); + } + function h(uint8[] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) { + return this.h(s[which]); + } + function j(bytes calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) { + return this.j(s[which]); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87 +// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87 +// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27 +// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87 +// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87 +// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27 +// j(bytes): 32, 3, hex"AB11FF" -> 32, 96, 32, 3, left(0xAB11FF) +// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex"AB11FF", 4, hex"FF791432" -> 32, 96, 32, 3, left(0xAB11FF) +// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex"AB11FF", 4, hex"FF791432" -> 32, 96, 32, 4, left(0xFF791432) diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access_standard_input.json new file mode 100644 index 00000000..8f585b31 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_index_access/calldata_array_dynamic_index_access_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic.sol new file mode 100644 index 00000000..ecea716b --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic.sol @@ -0,0 +1,49 @@ +pragma abicoder v2; + +contract C { + function f(uint8[][1][] calldata s) external pure returns (bytes memory) { + return msg.data; + } + function f2(uint256[][2][] calldata s) external pure returns (bytes memory) { + return msg.data; + } + function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) { + return this.f(s); + } + function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) { + return this.f2(s); + } + function g() external returns (bytes memory) { + uint8[][1][] memory m = new uint8[][1][](1); + m[0][0] = new uint8[](1); + m[0][0][0] = 42; + return this.f(m); + } + function h() external returns (bytes memory) { + uint8[][1][] memory m = new uint8[][1][](1); + m[0][0] = new uint8[](1); + m[0][0][0] = 42; + return this.reenc_f(m); + } + function i() external returns (bytes memory) { + uint256[][2][] memory m = new uint256[][2][](1); + m[0][0] = new uint256[](1); + m[0][1] = new uint256[](1); + m[0][0][0] = 42; + m[0][1][0] = 42; + return this.f2(m); + } + function j() external returns (bytes memory) { + uint256[][2][] memory m = new uint256[][2][](1); + m[0][0] = new uint256[](1); + m[0][1] = new uint256[](1); + m[0][0][0] = 42; + m[0][1][0] = 42; + return this.reenc_f2(m); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// g() -> 32, 196, hex"eccb829a", 32, 1, 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000" +// h() -> 32, 196, hex"eccb829a", 32, 1, 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic_standard_input.json new file mode 100644 index 00000000..cb547c95 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_dynamic/calldata_array_dynamic_static_dynamic_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library.sol new file mode 100644 index 00000000..b15a203f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library.sol @@ -0,0 +1,17 @@ +library L { + // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug. + function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) { + return (a, b); + } +} + +contract C { + function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) { + return L.g(a, b); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library_standard_input.json new file mode 100644 index 00000000..294474f1 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_in_library/calldata_array_dynamic_static_in_library_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol new file mode 100644 index 00000000..2d809570 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; +contract C { + function f(uint256[][2][] calldata x) external returns (uint256) { + x[0]; // trigger bounds checks + return 23; + } +} +// ---- +// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 # +// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding # +// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR # diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json new file mode 100644 index 00000000..817ea83f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol new file mode 100644 index 00000000..170f8864 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; +contract C { + function f(uint256[][2][] calldata x) external returns (uint256) { + return 42; + } + function g(uint256[][2][] calldata x) external returns (uint256) { + return this.f(x); + } +} +// ---- +// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 42 +// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 42 +// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json new file mode 100644 index 00000000..17990e4a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + }, + "calldata_nested_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function g(uint8[][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function h(uint16[][2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function i(uint16[][][1] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function j(uint16[2][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n" + }, + "abi_encoder_v2_head_overflow_with_static_array_cleanup_bug.sol": { + "content": "pragma abicoder v2;\n\nstruct T {\n bytes x;\n uint[3] y;\n}\n\ncontract E {\n function f(bool a, T calldata b, bytes32[2] calldata c)\n public\n returns (bool, T calldata, bytes32[2] calldata)\n {\n return (a, b, c);\n }\n}\n// ----\n// f(bool,(bytes,uint256[3]),bytes32[2]): 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\" -> 1, 0x80, \"a\", \"b\", 0x80, 11, 12, 13, 4, \"abcd\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 42\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types.sol new file mode 100644 index 00000000..a52a065e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types.sol @@ -0,0 +1,30 @@ +pragma abicoder v2; + +contract C { + function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) { + assert(s.length == 3); + return (s[0](), s[1](), s[2]()); + } + function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) { + return this.f(s); + } + function getter1() external returns (uint) { + return 23; + } + function getter2() external returns (uint) { + return 37; + } + function getter3() external returns (uint) { + return 71; + } + function g(bool reenc) external returns (uint, uint, uint) { + function() external returns (uint)[] memory a = new function() external returns (uint)[](3); + a[0] = this.getter1; + a[1] = this.getter2; + a[2] = this.getter3; + return reenc ? this.f_reenc(a) : this.f(a); + } +} +// ---- +// g(bool): false -> 23, 37, 71 +// g(bool): true -> 23, 37, 71 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types_standard_input.json new file mode 100644 index 00000000..f6900a04 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_function_types/calldata_array_function_types_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic.sol new file mode 100644 index 00000000..b9b3bd14 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic.sol @@ -0,0 +1,31 @@ +pragma abicoder v2; + +contract C { + function f(uint256[][] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function g(uint256[][] calldata s) external view returns (bytes memory) { + return this.f(s); + } + function h(uint8[][] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function i(uint8[][] calldata s) external view returns (bytes memory) { + return this.h(s); + } + function j(bytes[] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function k(bytes[] calldata s) external view returns (bytes memory) { + return this.j(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41 +// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41 +// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41 +// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41 +// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex"131723", 4, hex"27313741" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741) +// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex"131723", 4, hex"27313741" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741) diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic_standard_input.json new file mode 100644 index 00000000..327c3f6f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_multi_dynamic/calldata_array_multi_dynamic_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short.sol new file mode 100644 index 00000000..b8cb0226 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; + +contract C { + function f(uint[] calldata) public {} +} +// ==== +// revertStrings: debug +// ---- +// f(uint256[]): 0x20, 0 -> +// f(uint256[]): 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x2b, "ABI decoding: invalid calldata a", "rray stride" +// f(uint256[]): 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x2b, "ABI decoding: invalid calldata a", "rray stride" diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short_standard_input.json new file mode 100644 index 00000000..d1501256 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_short/calldata_array_short_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string.sol new file mode 100644 index 00000000..7fc08caa --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint[] calldata) public {} +} +// ---- +// f(uint256[]): 0x20, 0 -> +// f(uint256[]): 0x20, 1 -> FAILURE +// f(uint256[]): 0x20, 2 -> FAILURE + diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string_standard_input.json new file mode 100644 index 00000000..2f64a4b1 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_short_no_revert_string/calldata_array_short_no_revert_string_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static.sol new file mode 100644 index 00000000..aaf7616e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + function f(uint256[3] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function g(uint256[3] calldata s) external view returns (bytes memory) { + return this.f(s); + } + function h(uint8[3] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function i(uint8[3] calldata s) external view returns (bytes memory) { + return this.h(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87 +// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87 +// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87 +// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87 +// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE +// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static_standard_input.json new file mode 100644 index 00000000..6db8c2ed --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_static/calldata_array_static_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static.sol new file mode 100644 index 00000000..dd59ac8c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static.sol @@ -0,0 +1,49 @@ +pragma abicoder v2; + +contract C { + function f(uint8[1][][1] calldata s) external pure returns (bytes memory) { + return msg.data; + } + function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) { + return msg.data; + } + function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) { + return this.f(s); + } + function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) { + return this.f2(s); + } + function g() external returns (bytes memory) { + uint8[1][][1] memory m = [new uint8[1][](1)]; + m[0][0][0] = 42; + return this.f(m); + } + function h() external returns (bytes memory) { + uint8[1][][1] memory m = [new uint8[1][](1)]; + m[0][0][0] = 42; + return this.reenc_f(m); + } + function i() external returns (bytes memory) { + uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)]; + m[0][0][0] = 0x00042; + m[0][0][1] = 0x00142; + m[1][0][0] = 0x10042; + m[1][0][1] = 0x10142; + return this.f2(m); + } + function j() external returns (bytes memory) { + uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)]; + m[0][0][0] = 0x00042; + m[0][0][1] = 0x00142; + m[1][0][0] = 0x10042; + m[1][0][1] = 0x10142; + return this.reenc_f2(m); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// g() -> 32, 132, hex"15cfcc01", 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000" +// h() -> 32, 132, hex"15cfcc01", 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000" +// i() -> 32, 292, hex"dc0ee233", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex"00000000000000000000000000000000000000000000000000000000" +// j() -> 32, 292, hex"dc0ee233", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex"00000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static_standard_input.json new file mode 100644 index 00000000..323094b4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_dynamic_static/calldata_array_static_dynamic_static_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access.sol new file mode 100644 index 00000000..a75e2c2e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + function f(uint256[3] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) { + return this.f(s[which]); + } + function h(uint8[3] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) { + return this.h(s[which]); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87 +// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87 +// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187 +// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87 +// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87 +// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access_standard_input.json new file mode 100644 index 00000000..0b5aab3f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_static_index_access/calldata_array_static_index_access_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic.sol new file mode 100644 index 00000000..68dbe88f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + struct S { uint256[] a; } + function f(S[] calldata s) external pure returns (bytes memory) { + return abi.encode(s); + } + function g(S[] calldata s) external view returns (bytes memory) { + return this.f(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23 +// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic_standard_input.json new file mode 100644 index 00000000..286f1864 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_struct_dynamic/calldata_array_struct_dynamic_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic.sol new file mode 100644 index 00000000..5e43a1c4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) { + if (which) + return abi.encode(s1); + else + return abi.encode(s2); + } + function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) { + return this.f(s1, s2, which); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87 +// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72 +// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87 +// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic_standard_input.json new file mode 100644 index 00000000..9d3d87d3 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_dynamic/calldata_array_two_dynamic_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static.sol b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static.sol new file mode 100644 index 00000000..554c06aa --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) { + if (which) + return abi.encode(s1); + else + return abi.encode(s2); + } + function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) { + return this.f(s1, s2, which); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87 +// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72 +// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87 +// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static_standard_input.json new file mode 100644 index 00000000..6bee3778 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_array_two_static/calldata_array_two_static_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol b/examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol new file mode 100644 index 00000000..1fca188a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + +contract C { + function f(uint[][] calldata a) public returns (uint[][] memory) { + return a; + } + + function g(uint[][][] calldata a) public returns (uint[][][] memory) { + return a; + } + + function h(uint[2][][] calldata a) public returns (uint[2][][] memory) { + return a; + } +} +// ---- +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE +// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 +// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE +// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 +// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 +// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json new file mode 100644 index 00000000..9129ec28 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode.sol b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode.sol new file mode 100644 index 00000000..96573fb4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; + +contract C { + function f(uint[][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function g(uint8[][][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function h(uint16[][2][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function i(uint16[][][1] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + function j(uint16[2][][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } +} +// ==== +// revertStrings: debug +// ---- +// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0 +// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access offset" +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 +// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 +// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 +// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 +// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" +// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15 +// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex"08c379a0", 0x20, 0x1e, "Invalid calldata access stride" diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode_standard_input.json new file mode 100644 index 00000000..4cfda036 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_reencode/calldata_nested_array_reencode_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + }, + "calldata_array_multi_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[][] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[] calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// g(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// h(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// i(uint8[][]): 0x20, 2, 0x40, 0xC0, 3, 13, 17, 23, 4, 27, 31, 37, 41 -> 32, 416, 32, 2, 64, 192, 3, 13, 17, 23, 4, 27, 31, 37, 41\n// j(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n// k(bytes[]): 0x20, 2, 0x40, 0x63, 3, hex\"131723\", 4, hex\"27313741\" -> 32, 256, 32, 2, 64, 128, 3, left(0x131723), 4, left(0x27313741)\n" + }, + "calldata_array_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// h(uint8[3]): 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[3]): 0xAB23, 0x1242, 0xFF87 -> FAILURE\n" + }, + "calldata_nested_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function g(uint8[][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function h(uint16[][2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function i(uint16[][][1] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n function j(uint16[2][][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 0x20, 0x80, 0x20, 1, 0x20, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// f(uint256[][]): 0x20, 1, 0x20, 3 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0 -> 0x20, 0x01a0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access offset\"\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// g(uint8[][][]): 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0, 1 -> 0x20, 0x01e0, 0x20, 2, 0x40, 0x0140, 2, 0x40, 0x80, 1, 10, 2, 11, 12, 1, 0x20, 0\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13 -> 0x20, 0x0200, 0x20, 2, 0x40, 288, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1, 13\n// h(uint16[][2][]): 0x20, 2, 0x40, 0x0120, 0x40, 0x80, 1, 10, 2, 11, 12, 0x40, 0x60, 0, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12 -> 0x20, 0x0140, 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11, 12\n// i(uint16[][][1]): 0x20, 0x20, 2, 0x40, 0x80, 1, 10, 2, 11 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14, 15 -> 0x20, 0x0180, 0x20, 2, 0x40, 0xa0, 1, 10, 11, 2, 12, 13, 14, 15\n// j(uint16[2][][]): 0x20, 2, 0x40, 0xa0, 1, 0x0a, 11, 2, 12, 13, 14 -> FAILURE, hex\"08c379a0\", 0x20, 0x1e, \"Invalid calldata access stride\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode.sol b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode.sol new file mode 100644 index 00000000..440f8e14 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + function f(uint[3][] calldata a) public { + abi.encode(a); + } + function f(uint[][3] calldata a) public { + abi.encode(a); + } + function f(uint[2][2] calldata a) public { + abi.encode(a); + } +} +// ---- +// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE +// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE +// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 -> +// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE +// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE +// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 -> +// f(uint256[2][2]): 0x01 -> FAILURE +// f(uint256[2][2]): 0x01, 0x02 -> FAILURE +// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE +// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 -> +// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 -> diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode_standard_input.json new file mode 100644 index 00000000..88f25e6c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_nested_array_static_reencode/calldata_nested_array_static_reencode_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays.sol b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays.sol new file mode 100644 index 00000000..aa1e494c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +contract C { + uint[] s; + uint[2] n; + + function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) { + return (a, b); + } + + function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) { + return abi.encode(a[which], b[1]); + } + + function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) { + s = a; + n = b; + return abi.encode(s); + } +} +// ---- +// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2 +// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6 +// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE +// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2 +// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6 +// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE +// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2 +// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2 +// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE +// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2 +// gas irOptimized: 111409 +// gas legacy: 112707 +// gas legacyOptimized: 111845 +// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6 +// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays_standard_input.json new file mode 100644 index 00000000..d4d5ce62 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_dynamic_arrays/calldata_overlapped_dynamic_arrays_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays.sol b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays.sol new file mode 100644 index 00000000..d5a3266f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays.sol @@ -0,0 +1,34 @@ +pragma abicoder v2; + +contract C { + uint[] s; + uint[2] n; + + function f_memory(uint[][] calldata a) public returns (uint[][] memory) { + return a; + } + + function f_encode(uint[][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) { + return a[which]; + } +} +// ---- +// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2 +// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2 +// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2 +// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE +// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2 +// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2 +// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2 +// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE +// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2 +// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2 +// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2 +// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays_standard_input.json new file mode 100644 index 00000000..79ab4609 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_overlapped_nested_dynamic_arrays/calldata_overlapped_nested_dynamic_arrays_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode.sol b/examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode.sol new file mode 100644 index 00000000..347710a3 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode.sol @@ -0,0 +1,53 @@ +pragma abicoder v2; + +contract C { + struct D { uint[] x; } + struct S { uint x; } + + function f(D calldata a) public returns (bytes memory){ + return abi.encode(a); + } + + function g(D[2] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function h(D[][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function i(D[2][] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function j(S[] memory a) public returns (bytes memory) { + return abi.encode(a); + } + + function k(S[2] memory a) public returns (bytes memory) { + return abi.encode(a); + } + + function l(S[][] memory a) public returns (bytes memory) { + return abi.encode(a); + } + +} +// ---- +// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0 +// f((uint256[])): 0x20, 0x20, 1 -> FAILURE +// f((uint256[])): 0x20, 0x20, 2 -> FAILURE +// f((uint256[])): 0x20, 0x20, 3 -> FAILURE +// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 +// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE +// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 +// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE +// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 +// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE +// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2 +// j((uint256)[]): 0x20, 2, 1 -> FAILURE +// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2 +// k((uint256)[2]): 1 -> FAILURE +// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 +// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 +// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode_standard_input.json new file mode 100644 index 00000000..03694622 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_array_reencode/calldata_struct_array_reencode_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic.sol b/examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic.sol new file mode 100644 index 00000000..f275957c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + +contract C { + struct S { uint256[] a; } + + function f(S calldata s) external returns (bytes memory) { + return abi.encode(s); + } + + function g(S calldata s) external returns (bytes memory) { + return this.f(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17 +// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic_standard_input.json new file mode 100644 index 00000000..c8f246c8 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_dynamic/calldata_struct_dynamic_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset.sol b/examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset.sol new file mode 100644 index 00000000..129373de --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + +contract C { + struct A { + uint256 a; + uint256[] b; + } + struct B { + A a; + uint256 b; + } + function g(B calldata b) external pure returns(uint256) { + return b.b; + } + function f() public view returns(uint256, uint256) { + uint256[] memory arr = new uint256[](20); + arr[0] = 31; arr[2] = 84; + B memory b = B(A(420, arr), 11); + return (b.b, this.g(b)); + } +} +// ---- +// f() -> 11, 11 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset_standard_input.json new file mode 100644 index 00000000..0dbd0c21 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_member_offset/calldata_struct_member_offset_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple.sol b/examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple.sol new file mode 100644 index 00000000..4c85fe76 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + +contract C { + struct S { uint256 a; } + + function f(S calldata s) external returns (bytes memory) { + return abi.encode(s); + } + + function g(S calldata s) external returns (bytes memory) { + return this.f(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f((uint256)): 3 -> 32, 32, 3 +// g((uint256)): 3 -> 32, 32, 3 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple_standard_input.json new file mode 100644 index 00000000..02f560c7 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_struct_simple/calldata_struct_simple_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access.sol b/examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access.sol new file mode 100644 index 00000000..745bebe7 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +contract C { + struct S { uint[] a; } + + function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) { + return abi.encode(s[i][j]); + } + + function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) { + return abi.encode(s[i][j][k]); + } + + function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) { + return abi.encode(s[0][i]); + } + + function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) { + return abi.encode(s[i][j].a); + } + + function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) { + return abi.encode(s[i][j].a); + } +} +// ==== +// revertStrings: debug +// ---- +// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7 +// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex"4e487b71", 0x32 +// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9 +// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex"4e487b71", 0x32 +// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6 +// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex"4e487b71", 0x32 +// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9 +// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access_standard_input.json new file mode 100644 index 00000000..62490829 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_three_dimensional_dynamic_array_index_access/calldata_three_dimensional_dynamic_array_index_access_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage.sol b/examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage.sol new file mode 100644 index 00000000..58f68b8c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage.sol @@ -0,0 +1,66 @@ +pragma abicoder v2; + +contract C { + uint[] aTmp; + uint[2] bTmp; + + function f_memory(uint[] calldata a) public returns (uint[] memory) { + return a; + } + + function f_encode(uint[] calldata a) public returns (bytes memory) { + return abi.encode(a); + } + + function f_storage(uint[] calldata a) public returns (bytes memory) { + aTmp = a; + return abi.encode(aTmp); + } + + function f_index(uint[] calldata a, uint which) public returns (uint) { + return a[which]; + } + + function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) { + return (a, b); + } + + function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) { + aTmp = a; + bTmp = b; + return abi.encode(aTmp, bTmp); + } + + function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) { + return (a[which], b[0]); + } +} +// ---- +// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0 +// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7 +// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE +// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0 +// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7 +// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE +// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0 +// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7 +// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE +// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7 +// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8 +// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex"4e487b71", 0x32 +// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0 +// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7 +// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE +// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0 +// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7 +// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE +// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0 +// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7 +// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE +// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1 +// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1 +// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage_standard_input.json b/examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage_standard_input.json new file mode 100644 index 00000000..59010a78 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_calldata_with_garbage/calldata_with_garbage_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_address/address.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_address/address.sol new file mode 100644 index 00000000..44a462d1 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_address/address.sol @@ -0,0 +1,31 @@ +pragma abicoder v2; + +contract C { + function g(address x) external pure returns (uint256 r) { + assembly { r := x } + } + function f(uint256 a) external view returns (uint256) { + address x; + assembly { x := a } + return this.g(x); + } +} +// ---- +// f(uint256): 0 -> 0 +// g(address): 0 -> 0 # test validation as well as sanity check # +// f(uint256): 1 -> 1 +// g(address): 1 -> 1 +// f(uint256): 2 -> 2 +// g(address): 2 -> 2 +// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// f(uint256): 0x010000000000000000000000000000000000000000 -> 0 +// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE +// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff +// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE +// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE +// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff +// g(address): -1 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_address/address_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_address/address_standard_input.json new file mode 100644 index 00000000..068e68da --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_address/address_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool.sol new file mode 100644 index 00000000..8e788ab8 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + function gggg(bool x) external pure returns (bool) { + return x; + } + function f(uint256 a) external view returns (bool) { + bool x = false; + assembly { x := a } + return this.gggg(x); + } +} +// ---- +// f(uint256): 0 -> false +// gggg(bool): 0 -> false # test validation as well as sanity check # +// f(uint256): 1 -> true +// gggg(bool): 1 -> true +// f(uint256): 2 -> true +// gggg(bool): 2 -> FAILURE +// f(uint256): 0x1000 -> true +// gggg(bool): 0x1000 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool_standard_input.json new file mode 100644 index 00000000..15a5644c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_bool/bool_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx.sol new file mode 100644 index 00000000..92cffdd8 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx.sol @@ -0,0 +1,115 @@ +pragma abicoder v2; + +contract C { + function gg1(bytes1 x) external pure returns (bytes32) { + return x; + } + function f1(bytes32 a) external view returns (bytes32) { + bytes1 x; + assembly { x := a } + return this.gg1(x); + } + function gg2(bytes2 x) external pure returns (bytes32) { + return x; + } + function f2(bytes32 a) external view returns (bytes32) { + bytes2 x; + assembly { x := a } + return this.gg2(x); + } + function gg4(bytes4 x) external pure returns (bytes32) { + return x; + } + function f4(bytes32 a) external view returns (bytes32) { + bytes4 x; + assembly { x := a } + return this.gg4(x); + } + function gg8(bytes8 x) external pure returns (bytes32) { + return x; + } + function f8(bytes32 a) external view returns (bytes32) { + bytes8 x; + assembly { x := a } + return this.gg8(x); + } + function g16(bytes16 x) external pure returns (bytes32) { + return x; + } + function f16(bytes32 a) external view returns (bytes32) { + bytes16 x; + assembly { x := a } + return this.g16(x); + } +} +// ---- +// f1(bytes32): left(0) -> left(0) +// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check # +// f1(bytes32): left(1) -> left(1) +// gg1(bytes1): left(1) -> left(1) +// f1(bytes32): left(0xFE) -> left(0xFE) +// gg1(bytes1): left(0xFE) -> left(0xFE) +// f1(bytes32): left(0xFF) -> left(0xFF) +// gg1(bytes1): left(0xFF) -> left(0xFF) +// f1(bytes32): left(0x0001) -> left(0x00) +// gg1(bytes1): left(0x0001) -> FAILURE +// f1(bytes32): left(0x0101) -> left(0x01) +// gg1(bytes1): left(0x0101) -> FAILURE +// f1(bytes32): -1 -> left(0xFF) +// gg1(bytes1): -1 -> FAILURE +// f2(bytes32): left(0) -> left(0) +// gg2(bytes2): left(0) -> left(0) +// f2(bytes32): left(1) -> left(1) +// gg2(bytes2): left(1) -> left(1) +// f2(bytes32): left(0xFFFE) -> left(0xFFFE) +// gg2(bytes2): left(0xFFFE) -> left(0xFFFE) +// f2(bytes32): left(0xFFFF) -> left(0xFFFF) +// gg2(bytes2): left(0xFFFF) -> left(0xFFFF) +// f2(bytes32): left(0x000001) -> left(0x00) +// gg2(bytes2): left(0x000001) -> FAILURE +// f2(bytes32): left(0x010001) -> left(0x01) +// gg2(bytes2): left(0x010001) -> FAILURE +// f2(bytes32): -1 -> left(0xFFFF) +// gg2(bytes2): -1 -> FAILURE +// f4(bytes32): left(0) -> left(0) +// gg4(bytes4): left(0) -> left(0) +// f4(bytes32): left(1) -> left(1) +// gg4(bytes4): left(1) -> left(1) +// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE) +// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE) +// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF) +// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF) +// f4(bytes32): left(0x0000000001) -> left(0x00) +// gg4(bytes4): left(0x0000000001) -> FAILURE +// f4(bytes32): left(0x0100000001) -> left(0x01) +// gg4(bytes4): left(0x0100000001) -> FAILURE +// f4(bytes32): -1 -> left(0xFFFFFFFF) +// gg4(bytes4): -1 -> FAILURE +// f8(bytes32): left(0) -> left(0) +// gg8(bytes8): left(0) -> left(0) +// f8(bytes32): left(1) -> left(1) +// gg8(bytes8): left(1) -> left(1) +// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE) +// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE) +// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF) +// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF) +// f8(bytes32): left(0x000000000000000001) -> left(0x00) +// gg8(bytes8): left(0x000000000000000001) -> FAILURE +// f8(bytes32): left(0x010000000000000001) -> left(0x01) +// gg8(bytes8): left(0x010000000000000001) -> FAILURE +// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF) +// gg8(bytes8): -1 -> FAILURE +// f16(bytes32): left(0) -> left(0) +// g16(bytes16): left(0) -> left(0) +// f16(bytes32): left(1) -> left(1) +// g16(bytes16): left(1) -> left(1) +// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) +// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) +// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00) +// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE +// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01) +// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE +// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +// g16(bytes16): -1 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx_standard_input.json new file mode 100644 index 00000000..50881b2e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_bytesx/bytesx_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup.sol new file mode 100644 index 00000000..4286f8f0 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + function f(uint16 a, int16 b, address c, bytes3 d, bool e) + public pure returns (uint v, uint w, uint x, uint y, uint z) { + assembly { v := a w := b x := c y := d z := e} + } +} +// ---- +// f(uint16,int16,address,bytes3,bool): 1, 2, 3, "a", true -> 1, 2, 3, "a", true +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "abcd", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, "bcd", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, "ab", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "ad", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abcd", 1 -> FAILURE +// f(uint16,int16,address,bytes3,bool): 0, 0, 0, "abc", 2 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup_standard_input.json new file mode 100644 index 00000000..a9d7588c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_cleanup/cleanup_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array.sol new file mode 100644 index 00000000..240ec623 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +contract C { + function ggg(uint8[] calldata s) external pure returns (bytes memory) { + s[0]; // only this will validate. + return msg.data; + } + function f(uint256[] calldata a) external returns (bytes memory) { + uint8[] memory m = new uint8[](a.length); + assembly { + calldatacopy(add(m, 0x20), 0x44, mul(calldataload(4), 0x20)) + } + return this.ggg(m); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex"304a4c23", 0x20, 2, 1, 1, hex"00000000000000000000000000000000000000000000000000000000" +// ggg(uint8[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex"304a4c23", 0x20, 2, 1, 1, hex"00000000000000000000000000000000000000000000000000000000" +// f(uint256[]): 0x20, 2, 0x0101, 0x0101 -> 0x20, 0x84, hex"304a4c23", 0x20, 2, 1, 1, hex"00000000000000000000000000000000000000000000000000000000" +// ggg(uint8[]): 0x20, 2, 0x0101, 0x0101 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array_standard_input.json new file mode 100644 index 00000000..f5d4119f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_dynamic_array/dynamic_array_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n" + }, + "function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function() external f; }\n function ggg(function() external x) external pure returns (uint256 r) {\n assembly { r := calldataload(4) }\n }\n function h(S calldata x) external pure returns (uint256 r) {\n x.f; // validation only happens here\n assembly { r := calldataload(4) }\n }\n function dummy() external {}\n function ffff(uint256 a) external view returns (uint256, uint256) {\n S memory s = S(this.dummy);\n assembly { mstore(s, a) }\n return (this.ggg(s.f), this.h(s));\n }\n}\n// ----\n// ffff(uint256): 0 -> 0, 0\n// ggg(function): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcdX\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcdX\" -> FAILURE\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + }, + "uintx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(uint8 x) external pure returns (uint256) {\n return x;\n }\n function gg16(uint16 x) external pure returns (uint256) {\n return x;\n }\n function gg32(uint32 x) external pure returns (uint256) {\n return x;\n }\n function gg64(uint64 x) external pure returns (uint256) {\n return x;\n }\n function g128(uint128 x) external pure returns (uint256) {\n return x;\n }\n function f8(uint256 a) external view returns (uint256) {\n uint8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(uint256 a) external view returns (uint256) {\n uint16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(uint256 a) external view returns (uint256) {\n uint32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(uint256 a) external view returns (uint256) {\n uint64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(uint256 a) external view returns (uint256) {\n uint128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(uint256): 0 -> 0\n// ggg8(uint8): 0 -> 0 # test validation as well as sanity check #\n// f8(uint256): 1 -> 1\n// ggg8(uint8): 1 -> 1\n// f8(uint256): 0xFE -> 0xFE\n// ggg8(uint8): 0xFE -> 0xFE\n// f8(uint256): 0xFF -> 0xFF\n// ggg8(uint8): 0xFF -> 0xFF\n// f8(uint256): 0x0100 -> 0x00\n// ggg8(uint8): 0x0100 -> FAILURE\n// f8(uint256): 0x0101 -> 0x01\n// ggg8(uint8): 0x0101 -> FAILURE\n// f8(uint256): -1 -> 0xFF\n// ggg8(uint8): -1 -> FAILURE\n// f16(uint256): 0 -> 0\n// gg16(uint16): 0 -> 0\n// f16(uint256): 1 -> 1\n// gg16(uint16): 1 -> 1\n// f16(uint256): 0xFFFE -> 0xFFFE\n// gg16(uint16): 0xFFFE -> 0xFFFE\n// f16(uint256): 0xFFFF -> 0xFFFF\n// gg16(uint16): 0xFFFF -> 0xFFFF\n// f16(uint256): 0x010000 -> 0x0000\n// gg16(uint16): 0x010000 -> FAILURE\n// f16(uint256): 0x010001 -> 0x0001\n// gg16(uint16): 0x010001 -> FAILURE\n// f16(uint256): -1 -> 0xFFFF\n// gg16(uint16): -1 -> FAILURE\n// f32(uint256): 0 -> 0\n// gg32(uint32): 0 -> 0\n// f32(uint256): 1 -> 1\n// gg32(uint32): 1 -> 1\n// f32(uint256): 0xFFFFFFFE -> 0xFFFFFFFE\n// gg32(uint32): 0xFFFFFFFE -> 0xFFFFFFFE\n// f32(uint256): 0xFFFFFFFF -> 0xFFFFFFFF\n// gg32(uint32): 0xFFFFFFFF -> 0xFFFFFFFF\n// f32(uint256): 0x0100000000 -> 0x00000000\n// gg32(uint32): 0x0100000000 -> FAILURE\n// f32(uint256): 0x0100000001 -> 0x00000001\n// gg32(uint32): 0x0100000001 -> FAILURE\n// f32(uint256): -1 -> 0xFFFFFFFF\n// gg32(uint32): -1 -> FAILURE\n// f64(uint256): 0 -> 0\n// gg64(uint64): 0 -> 0\n// f64(uint256): 1 -> 1\n// gg64(uint64): 1 -> 1\n// f64(uint256): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// gg64(uint64): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// f64(uint256): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// f64(uint256): 0x010000000000000000 -> 0x0000000000000000\n// gg64(uint64): 0x010000000000000000 -> FAILURE\n// f64(uint256): 0x010000000000000001 -> 0x0000000000000001\n// gg64(uint64): 0x010000000000000001 -> FAILURE\n// f64(uint256): -1 -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): -1 -> FAILURE\n// f128(uint256): 0 -> 0\n// g128(uint128): 0 -> 0\n// f128(uint256): 1 -> 1\n// g128(uint128): 1 -> 1\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(uint256): 0x0100000000000000000000000000000000 -> 0x00000000000000000000000000000000\n// g128(uint128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(uint256): 0x0100000000000000000000000000000001 -> 0x00000000000000000000000000000001\n// g128(uint128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(uint256): -1 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): -1 -> FAILURE\n" + }, + "static_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggggggg(uint8[2] calldata s) external pure returns (bytes memory) {\n s[0]; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, uint256 b) public returns (bytes memory) {\n uint8[2] memory m = [0,0];\n assembly {\n mstore(m, a)\n mstore(add(m, 0x20), b)\n }\n return this.gggggggg(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,uint256): 0x0101, 0x0101 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 0x0101, 0x0101 -> FAILURE\n" + }, + "reencoded_calldata_string.sol": { + "content": "contract C {\n function f(string calldata x) external returns (bytes memory r) {\n uint mptr;\n assembly {\n // dirty memory\n mptr := mload(0x40)\n for { let i := mptr } lt(i, add(mptr, 0x0100)) { i := add(i, 32) }\n {\n mstore(i, sub(0, 1))\n }\n }\n r = abi.encode(x);\n assembly {\n // assert that we dirtied the memory that was encoded to\n if iszero(eq(mptr, r)) {\n revert(0, 0)\n }\n }\n }\n function test() external returns (bytes memory) {\n return this.f(\"abc\");\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> 0x20, 0x60, 0x20, 3, \"abc\"\n" + }, + "dynamic_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg(uint8[] calldata s) external pure returns (bytes memory) {\n s[0]; // only this will validate.\n return msg.data;\n }\n function f(uint256[] calldata a) external returns (bytes memory) {\n uint8[] memory m = new uint8[](a.length);\n assembly {\n calldatacopy(add(m, 0x20), 0x44, mul(calldataload(4), 0x20))\n }\n return this.ggg(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex\"304a4c23\", 0x20, 2, 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// ggg(uint8[]): 0x20, 2, 1, 1 -> 0x20, 0x84, hex\"304a4c23\", 0x20, 2, 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256[]): 0x20, 2, 0x0101, 0x0101 -> 0x20, 0x84, hex\"304a4c23\", 0x20, 2, 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// ggg(uint8[]): 0x20, 2, 0x0101, 0x0101 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_function/function.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_function/function.sol new file mode 100644 index 00000000..1ae459d2 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_function/function.sol @@ -0,0 +1,28 @@ +pragma abicoder v2; + +contract C { + struct S { function() external f; } + function ggg(function() external x) external pure returns (uint256 r) { + assembly { r := calldataload(4) } + } + function h(S calldata x) external pure returns (uint256 r) { + x.f; // validation only happens here + assembly { r := calldataload(4) } + } + function dummy() external {} + function ffff(uint256 a) external view returns (uint256, uint256) { + S memory s = S(this.dummy); + assembly { mstore(s, a) } + return (this.ggg(s.f), this.h(s)); + } +} +// ---- +// ffff(uint256): 0 -> 0, 0 +// ggg(function): 0 -> 0 +// ffff(uint256): "01234567890123456789abcd" -> "01234567890123456789abcd", "01234567890123456789abcd" +// ggg(function): "01234567890123456789abcd" -> "01234567890123456789abcd" +// h((function)): "01234567890123456789abcd" -> "01234567890123456789abcd" +// h((function)): 0 -> 0 +// ffff(uint256): "01234567890123456789abcdX" -> "01234567890123456789abcd", "01234567890123456789abcd" +// ggg(function): "01234567890123456789abcdX" -> FAILURE +// h((function)): "01234567890123456789abcdX" -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_function/function_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_function/function_standard_input.json new file mode 100644 index 00000000..dd7bd9c0 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_function/function_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n" + }, + "function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function() external f; }\n function ggg(function() external x) external pure returns (uint256 r) {\n assembly { r := calldataload(4) }\n }\n function h(S calldata x) external pure returns (uint256 r) {\n x.f; // validation only happens here\n assembly { r := calldataload(4) }\n }\n function dummy() external {}\n function ffff(uint256 a) external view returns (uint256, uint256) {\n S memory s = S(this.dummy);\n assembly { mstore(s, a) }\n return (this.ggg(s.f), this.h(s));\n }\n}\n// ----\n// ffff(uint256): 0 -> 0, 0\n// ggg(function): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcdX\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcdX\" -> FAILURE\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx.sol new file mode 100644 index 00000000..8e60d5c3 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx.sol @@ -0,0 +1,155 @@ +pragma abicoder v2; + +contract C { + function ggg8(int8 x) external pure returns (int256) { + return x; + } + function gg16(int16 x) external pure returns (int256) { + return x; + } + function gg32(int32 x) external pure returns (int256) { + return x; + } + function gg64(int64 x) external pure returns (int256) { + return x; + } + function g128(int128 x) external pure returns (int256) { + return x; + } + function f8(int256 a) external view returns (int256) { + int8 x = 0; + assembly { x := a } + return this.ggg8(x); + } + function f16(int256 a) external view returns (int256) { + int16 x = 0; + assembly { x := a } + return this.gg16(x); + } + function f32(int256 a) external view returns (int256) { + int32 x = 0; + assembly { x := a } + return this.gg32(x); + } + function f64(int256 a) external view returns (int256) { + int64 x = 0; + assembly { x := a } + return this.gg64(x); + } + function f128(int256 a) external view returns (int256) { + int128 x = 0; + assembly { x := a } + return this.g128(x); + } +} +// ---- +// f8(int256): 0 -> 0 +// ggg8(int8): 0 -> 0 # test validation as well as sanity check # +// f8(int256): 1 -> 1 +// ggg8(int8): 1 -> 1 +// f8(int256): -1 -> -1 +// ggg8(int8): -1 -> -1 +// f8(int256): 0x7F -> 0x7F +// ggg8(int8): 0x7F -> 0x7F +// f8(int256): 0x80 -> -128 +// ggg8(int8): 0x80 -> FAILURE +// f8(int256): 0xFE -> -2 +// ggg8(int8): 0xFE -> FAILURE +// f8(int256): 0xFF -> -1 +// ggg8(int8): 0xFF -> FAILURE +// f8(int256): 0x0100 -> 0x00 +// ggg8(int8): 0x0100 -> FAILURE +// f8(int256): 0x0101 -> 0x01 +// ggg8(int8): 0x0101 -> FAILURE +// f8(int256): 0x01FF -> -1 +// ggg8(int8): 0x01FF -> FAILURE +// f8(int256): 0x01FE -> -2 +// ggg8(int8): 0x01FE -> FAILURE +// f16(int256): 0 -> 0 +// gg16(int16): 0 -> 0 +// f16(int256): 1 -> 1 +// gg16(int16): 1 -> 1 +// f16(int256): -1 -> -1 +// gg16(int16): -1 -> -1 +// f16(int256): 0x7FFF -> 0x7FFF +// gg16(int16): 0x7FFF -> 0x7FFF +// f16(int256): 0x8000 -> -32768 +// gg16(int16): 0x8000 -> FAILURE +// f16(int256): 0xFFFE -> -2 +// gg16(int16): 0xFFFE -> FAILURE +// f16(int256): 0xFFFF -> -1 +// gg16(int16): 0xFFFF -> FAILURE +// f16(int256): 0x010000 -> 0x00 +// gg16(int16): 0x010000 -> FAILURE +// f16(int256): 0x010001 -> 0x01 +// gg16(int16): 0x010001 -> FAILURE +// f16(int256): 0x01FFFF -> -1 +// gg16(int16): 0x01FFFF -> FAILURE +// f16(int256): 0x01FFFE -> -2 +// gg16(int16): 0x01FFFE -> FAILURE +// f32(int256): 0 -> 0 +// gg32(int32): 0 -> 0 +// f32(int256): 1 -> 1 +// gg32(int32): 1 -> 1 +// f32(int256): -1 -> -1 +// gg32(int32): -1 -> -1 +// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF +// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF +// f32(int256): 0x80000000 -> -2147483648 +// gg32(int32): 0x80000000 -> FAILURE +// f32(int256): 0xFFFFFFFE -> -2 +// gg32(int32): 0xFFFFFFFE -> FAILURE +// f32(int256): 0xFFFFFFFF -> -1 +// gg32(int32): 0xFFFFFFFF -> FAILURE +// f32(int256): 0x0100000000 -> 0x00 +// gg32(int32): 0x0100000000 -> FAILURE +// f32(int256): 0x0100000001 -> 0x01 +// gg32(int32): 0x0100000001 -> FAILURE +// f32(int256): 0x01FFFFFFFF -> -1 +// gg32(int32): 0x01FFFFFFFF -> FAILURE +// f32(int256): 0x01FFFFFFFE -> -2 +// gg32(int32): 0x01FFFFFFFE -> FAILURE +// f64(int256): 0 -> 0 +// gg64(int64): 0 -> 0 +// f64(int256): 1 -> 1 +// gg64(int64): 1 -> 1 +// f64(int256): -1 -> -1 +// gg64(int64): -1 -> -1 +// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF +// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF +// f64(int256): 0x8000000000000000 -> -9223372036854775808 +// gg64(int64): 0x8000000000000000 -> FAILURE +// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2 +// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE +// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1 +// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE +// f64(int256): 0x010000000000000000 -> 0x00 +// gg64(int64): 0x010000000000000000 -> FAILURE +// f64(int256): 0x010000000000000001 -> 0x01 +// gg64(int64): 0x010000000000000001 -> FAILURE +// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1 +// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE +// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2 +// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE +// f128(int256): 0 -> 0 +// g128(int128): 0 -> 0 +// f128(int256): 1 -> 1 +// g128(int128): 1 -> 1 +// f128(int256): -1 -> -1 +// g128(int128): -1 -> -1 +// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728 +// g128(int128): 0x80000000000000000000000000000000 -> FAILURE +// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2 +// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE +// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1 +// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE +// f128(int256): 0x0100000000000000000000000000000000 -> 0x00 +// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE +// f128(int256): 0x0100000000000000000000000000000001 -> 0x01 +// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE +// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1 +// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE +// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2 +// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx_standard_input.json new file mode 100644 index 00000000..12bc7312 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_intx/intx_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string.sol new file mode 100644 index 00000000..1cf12952 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string.sol @@ -0,0 +1,27 @@ +contract C { + function f(string calldata x) external returns (bytes memory r) { + uint mptr; + assembly { + // dirty memory + mptr := mload(0x40) + for { let i := mptr } lt(i, add(mptr, 0x0100)) { i := add(i, 32) } + { + mstore(i, sub(0, 1)) + } + } + r = abi.encode(x); + assembly { + // assert that we dirtied the memory that was encoded to + if iszero(eq(mptr, r)) { + revert(0, 0) + } + } + } + function test() external returns (bytes memory) { + return this.f("abc"); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// test() -> 0x20, 0x60, 0x20, 3, "abc" diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string_standard_input.json new file mode 100644 index 00000000..728c4b91 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_reencoded_calldata_string/reencoded_calldata_string_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n" + }, + "function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function() external f; }\n function ggg(function() external x) external pure returns (uint256 r) {\n assembly { r := calldataload(4) }\n }\n function h(S calldata x) external pure returns (uint256 r) {\n x.f; // validation only happens here\n assembly { r := calldataload(4) }\n }\n function dummy() external {}\n function ffff(uint256 a) external view returns (uint256, uint256) {\n S memory s = S(this.dummy);\n assembly { mstore(s, a) }\n return (this.ggg(s.f), this.h(s));\n }\n}\n// ----\n// ffff(uint256): 0 -> 0, 0\n// ggg(function): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcdX\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcdX\" -> FAILURE\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + }, + "uintx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(uint8 x) external pure returns (uint256) {\n return x;\n }\n function gg16(uint16 x) external pure returns (uint256) {\n return x;\n }\n function gg32(uint32 x) external pure returns (uint256) {\n return x;\n }\n function gg64(uint64 x) external pure returns (uint256) {\n return x;\n }\n function g128(uint128 x) external pure returns (uint256) {\n return x;\n }\n function f8(uint256 a) external view returns (uint256) {\n uint8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(uint256 a) external view returns (uint256) {\n uint16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(uint256 a) external view returns (uint256) {\n uint32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(uint256 a) external view returns (uint256) {\n uint64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(uint256 a) external view returns (uint256) {\n uint128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(uint256): 0 -> 0\n// ggg8(uint8): 0 -> 0 # test validation as well as sanity check #\n// f8(uint256): 1 -> 1\n// ggg8(uint8): 1 -> 1\n// f8(uint256): 0xFE -> 0xFE\n// ggg8(uint8): 0xFE -> 0xFE\n// f8(uint256): 0xFF -> 0xFF\n// ggg8(uint8): 0xFF -> 0xFF\n// f8(uint256): 0x0100 -> 0x00\n// ggg8(uint8): 0x0100 -> FAILURE\n// f8(uint256): 0x0101 -> 0x01\n// ggg8(uint8): 0x0101 -> FAILURE\n// f8(uint256): -1 -> 0xFF\n// ggg8(uint8): -1 -> FAILURE\n// f16(uint256): 0 -> 0\n// gg16(uint16): 0 -> 0\n// f16(uint256): 1 -> 1\n// gg16(uint16): 1 -> 1\n// f16(uint256): 0xFFFE -> 0xFFFE\n// gg16(uint16): 0xFFFE -> 0xFFFE\n// f16(uint256): 0xFFFF -> 0xFFFF\n// gg16(uint16): 0xFFFF -> 0xFFFF\n// f16(uint256): 0x010000 -> 0x0000\n// gg16(uint16): 0x010000 -> FAILURE\n// f16(uint256): 0x010001 -> 0x0001\n// gg16(uint16): 0x010001 -> FAILURE\n// f16(uint256): -1 -> 0xFFFF\n// gg16(uint16): -1 -> FAILURE\n// f32(uint256): 0 -> 0\n// gg32(uint32): 0 -> 0\n// f32(uint256): 1 -> 1\n// gg32(uint32): 1 -> 1\n// f32(uint256): 0xFFFFFFFE -> 0xFFFFFFFE\n// gg32(uint32): 0xFFFFFFFE -> 0xFFFFFFFE\n// f32(uint256): 0xFFFFFFFF -> 0xFFFFFFFF\n// gg32(uint32): 0xFFFFFFFF -> 0xFFFFFFFF\n// f32(uint256): 0x0100000000 -> 0x00000000\n// gg32(uint32): 0x0100000000 -> FAILURE\n// f32(uint256): 0x0100000001 -> 0x00000001\n// gg32(uint32): 0x0100000001 -> FAILURE\n// f32(uint256): -1 -> 0xFFFFFFFF\n// gg32(uint32): -1 -> FAILURE\n// f64(uint256): 0 -> 0\n// gg64(uint64): 0 -> 0\n// f64(uint256): 1 -> 1\n// gg64(uint64): 1 -> 1\n// f64(uint256): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// gg64(uint64): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// f64(uint256): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// f64(uint256): 0x010000000000000000 -> 0x0000000000000000\n// gg64(uint64): 0x010000000000000000 -> FAILURE\n// f64(uint256): 0x010000000000000001 -> 0x0000000000000001\n// gg64(uint64): 0x010000000000000001 -> FAILURE\n// f64(uint256): -1 -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): -1 -> FAILURE\n// f128(uint256): 0 -> 0\n// g128(uint128): 0 -> 0\n// f128(uint256): 1 -> 1\n// g128(uint128): 1 -> 1\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(uint256): 0x0100000000000000000000000000000000 -> 0x00000000000000000000000000000000\n// g128(uint128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(uint256): 0x0100000000000000000000000000000001 -> 0x00000000000000000000000000000001\n// g128(uint128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(uint256): -1 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): -1 -> FAILURE\n" + }, + "static_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggggggg(uint8[2] calldata s) external pure returns (bytes memory) {\n s[0]; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, uint256 b) public returns (bytes memory) {\n uint8[2] memory m = [0,0];\n assembly {\n mstore(m, a)\n mstore(add(m, 0x20), b)\n }\n return this.gggggggg(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,uint256): 0x0101, 0x0101 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 0x0101, 0x0101 -> FAILURE\n" + }, + "reencoded_calldata_string.sol": { + "content": "contract C {\n function f(string calldata x) external returns (bytes memory r) {\n uint mptr;\n assembly {\n // dirty memory\n mptr := mload(0x40)\n for { let i := mptr } lt(i, add(mptr, 0x0100)) { i := add(i, 32) }\n {\n mstore(i, sub(0, 1))\n }\n }\n r = abi.encode(x);\n assembly {\n // assert that we dirtied the memory that was encoded to\n if iszero(eq(mptr, r)) {\n revert(0, 0)\n }\n }\n }\n function test() external returns (bytes memory) {\n return this.f(\"abc\");\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> 0x20, 0x60, 0x20, 3, \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct.sol new file mode 100644 index 00000000..2a019f5e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + +contract C { + struct S { uint8 a; bytes1 b; } + function gg(S calldata s) external pure returns (bytes memory) { + s.a; s.b; // only this will validate. + return msg.data; + } + function f(uint256 a, bytes32 b) public returns (bytes memory) { + S memory s = S(2,0x02); + assembly { + mstore(s, a) + mstore(add(s, 0x20), b) + } + return this.gg(s); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex"b63240b0", 1, left(0x01), hex"00000000000000000000000000000000000000000000000000000000" +// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex"b63240b0", 1, left(0x01), hex"00000000000000000000000000000000000000000000000000000000" +// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex"b63240b0", 1, left(0x01), hex"00000000000000000000000000000000000000000000000000000000" +// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct_standard_input.json new file mode 100644 index 00000000..4ad2cbfd --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_simple_struct/simple_struct_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array.sol new file mode 100644 index 00000000..ce8cbfad --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + +contract C { + function gggggggg(uint8[2] calldata s) external pure returns (bytes memory) { + s[0]; // only this will validate. + return msg.data; + } + function f(uint256 a, uint256 b) public returns (bytes memory) { + uint8[2] memory m = [0,0]; + assembly { + mstore(m, a) + mstore(add(m, 0x20), b) + } + return this.gggggggg(m); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex"78b86ac6", 1, 1, hex"00000000000000000000000000000000000000000000000000000000" +// gggggggg(uint8[2]): 1, 1 -> 0x20, 0x44, hex"78b86ac6", 1, 1, hex"00000000000000000000000000000000000000000000000000000000" +// f(uint256,uint256): 0x0101, 0x0101 -> 0x20, 0x44, hex"78b86ac6", 1, 1, hex"00000000000000000000000000000000000000000000000000000000" +// gggggggg(uint8[2]): 0x0101, 0x0101 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array_standard_input.json new file mode 100644 index 00000000..9d4ccbf8 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_static_array/static_array_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n" + }, + "function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function() external f; }\n function ggg(function() external x) external pure returns (uint256 r) {\n assembly { r := calldataload(4) }\n }\n function h(S calldata x) external pure returns (uint256 r) {\n x.f; // validation only happens here\n assembly { r := calldataload(4) }\n }\n function dummy() external {}\n function ffff(uint256 a) external view returns (uint256, uint256) {\n S memory s = S(this.dummy);\n assembly { mstore(s, a) }\n return (this.ggg(s.f), this.h(s));\n }\n}\n// ----\n// ffff(uint256): 0 -> 0, 0\n// ggg(function): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcdX\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcdX\" -> FAILURE\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + }, + "uintx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(uint8 x) external pure returns (uint256) {\n return x;\n }\n function gg16(uint16 x) external pure returns (uint256) {\n return x;\n }\n function gg32(uint32 x) external pure returns (uint256) {\n return x;\n }\n function gg64(uint64 x) external pure returns (uint256) {\n return x;\n }\n function g128(uint128 x) external pure returns (uint256) {\n return x;\n }\n function f8(uint256 a) external view returns (uint256) {\n uint8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(uint256 a) external view returns (uint256) {\n uint16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(uint256 a) external view returns (uint256) {\n uint32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(uint256 a) external view returns (uint256) {\n uint64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(uint256 a) external view returns (uint256) {\n uint128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(uint256): 0 -> 0\n// ggg8(uint8): 0 -> 0 # test validation as well as sanity check #\n// f8(uint256): 1 -> 1\n// ggg8(uint8): 1 -> 1\n// f8(uint256): 0xFE -> 0xFE\n// ggg8(uint8): 0xFE -> 0xFE\n// f8(uint256): 0xFF -> 0xFF\n// ggg8(uint8): 0xFF -> 0xFF\n// f8(uint256): 0x0100 -> 0x00\n// ggg8(uint8): 0x0100 -> FAILURE\n// f8(uint256): 0x0101 -> 0x01\n// ggg8(uint8): 0x0101 -> FAILURE\n// f8(uint256): -1 -> 0xFF\n// ggg8(uint8): -1 -> FAILURE\n// f16(uint256): 0 -> 0\n// gg16(uint16): 0 -> 0\n// f16(uint256): 1 -> 1\n// gg16(uint16): 1 -> 1\n// f16(uint256): 0xFFFE -> 0xFFFE\n// gg16(uint16): 0xFFFE -> 0xFFFE\n// f16(uint256): 0xFFFF -> 0xFFFF\n// gg16(uint16): 0xFFFF -> 0xFFFF\n// f16(uint256): 0x010000 -> 0x0000\n// gg16(uint16): 0x010000 -> FAILURE\n// f16(uint256): 0x010001 -> 0x0001\n// gg16(uint16): 0x010001 -> FAILURE\n// f16(uint256): -1 -> 0xFFFF\n// gg16(uint16): -1 -> FAILURE\n// f32(uint256): 0 -> 0\n// gg32(uint32): 0 -> 0\n// f32(uint256): 1 -> 1\n// gg32(uint32): 1 -> 1\n// f32(uint256): 0xFFFFFFFE -> 0xFFFFFFFE\n// gg32(uint32): 0xFFFFFFFE -> 0xFFFFFFFE\n// f32(uint256): 0xFFFFFFFF -> 0xFFFFFFFF\n// gg32(uint32): 0xFFFFFFFF -> 0xFFFFFFFF\n// f32(uint256): 0x0100000000 -> 0x00000000\n// gg32(uint32): 0x0100000000 -> FAILURE\n// f32(uint256): 0x0100000001 -> 0x00000001\n// gg32(uint32): 0x0100000001 -> FAILURE\n// f32(uint256): -1 -> 0xFFFFFFFF\n// gg32(uint32): -1 -> FAILURE\n// f64(uint256): 0 -> 0\n// gg64(uint64): 0 -> 0\n// f64(uint256): 1 -> 1\n// gg64(uint64): 1 -> 1\n// f64(uint256): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// gg64(uint64): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// f64(uint256): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// f64(uint256): 0x010000000000000000 -> 0x0000000000000000\n// gg64(uint64): 0x010000000000000000 -> FAILURE\n// f64(uint256): 0x010000000000000001 -> 0x0000000000000001\n// gg64(uint64): 0x010000000000000001 -> FAILURE\n// f64(uint256): -1 -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): -1 -> FAILURE\n// f128(uint256): 0 -> 0\n// g128(uint128): 0 -> 0\n// f128(uint256): 1 -> 1\n// g128(uint128): 1 -> 1\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(uint256): 0x0100000000000000000000000000000000 -> 0x00000000000000000000000000000000\n// g128(uint128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(uint256): 0x0100000000000000000000000000000001 -> 0x00000000000000000000000000000001\n// g128(uint128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(uint256): -1 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): -1 -> FAILURE\n" + }, + "static_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggggggg(uint8[2] calldata s) external pure returns (bytes memory) {\n s[0]; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, uint256 b) public returns (bytes memory) {\n uint8[2] memory m = [0,0];\n assembly {\n mstore(m, a)\n mstore(add(m, 0x20), b)\n }\n return this.gggggggg(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,uint256): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 1, 1 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,uint256): 0x0101, 0x0101 -> 0x20, 0x44, hex\"78b86ac6\", 1, 1, hex\"00000000000000000000000000000000000000000000000000000000\"\n// gggggggg(uint8[2]): 0x0101, 0x0101 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx.sol b/examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx.sol new file mode 100644 index 00000000..9a33edda --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx.sol @@ -0,0 +1,115 @@ +pragma abicoder v2; + +contract C { + function ggg8(uint8 x) external pure returns (uint256) { + return x; + } + function gg16(uint16 x) external pure returns (uint256) { + return x; + } + function gg32(uint32 x) external pure returns (uint256) { + return x; + } + function gg64(uint64 x) external pure returns (uint256) { + return x; + } + function g128(uint128 x) external pure returns (uint256) { + return x; + } + function f8(uint256 a) external view returns (uint256) { + uint8 x = 0; + assembly { x := a } + return this.ggg8(x); + } + function f16(uint256 a) external view returns (uint256) { + uint16 x = 0; + assembly { x := a } + return this.gg16(x); + } + function f32(uint256 a) external view returns (uint256) { + uint32 x = 0; + assembly { x := a } + return this.gg32(x); + } + function f64(uint256 a) external view returns (uint256) { + uint64 x = 0; + assembly { x := a } + return this.gg64(x); + } + function f128(uint256 a) external view returns (uint256) { + uint128 x = 0; + assembly { x := a } + return this.g128(x); + } +} +// ---- +// f8(uint256): 0 -> 0 +// ggg8(uint8): 0 -> 0 # test validation as well as sanity check # +// f8(uint256): 1 -> 1 +// ggg8(uint8): 1 -> 1 +// f8(uint256): 0xFE -> 0xFE +// ggg8(uint8): 0xFE -> 0xFE +// f8(uint256): 0xFF -> 0xFF +// ggg8(uint8): 0xFF -> 0xFF +// f8(uint256): 0x0100 -> 0x00 +// ggg8(uint8): 0x0100 -> FAILURE +// f8(uint256): 0x0101 -> 0x01 +// ggg8(uint8): 0x0101 -> FAILURE +// f8(uint256): -1 -> 0xFF +// ggg8(uint8): -1 -> FAILURE +// f16(uint256): 0 -> 0 +// gg16(uint16): 0 -> 0 +// f16(uint256): 1 -> 1 +// gg16(uint16): 1 -> 1 +// f16(uint256): 0xFFFE -> 0xFFFE +// gg16(uint16): 0xFFFE -> 0xFFFE +// f16(uint256): 0xFFFF -> 0xFFFF +// gg16(uint16): 0xFFFF -> 0xFFFF +// f16(uint256): 0x010000 -> 0x0000 +// gg16(uint16): 0x010000 -> FAILURE +// f16(uint256): 0x010001 -> 0x0001 +// gg16(uint16): 0x010001 -> FAILURE +// f16(uint256): -1 -> 0xFFFF +// gg16(uint16): -1 -> FAILURE +// f32(uint256): 0 -> 0 +// gg32(uint32): 0 -> 0 +// f32(uint256): 1 -> 1 +// gg32(uint32): 1 -> 1 +// f32(uint256): 0xFFFFFFFE -> 0xFFFFFFFE +// gg32(uint32): 0xFFFFFFFE -> 0xFFFFFFFE +// f32(uint256): 0xFFFFFFFF -> 0xFFFFFFFF +// gg32(uint32): 0xFFFFFFFF -> 0xFFFFFFFF +// f32(uint256): 0x0100000000 -> 0x00000000 +// gg32(uint32): 0x0100000000 -> FAILURE +// f32(uint256): 0x0100000001 -> 0x00000001 +// gg32(uint32): 0x0100000001 -> FAILURE +// f32(uint256): -1 -> 0xFFFFFFFF +// gg32(uint32): -1 -> FAILURE +// f64(uint256): 0 -> 0 +// gg64(uint64): 0 -> 0 +// f64(uint256): 1 -> 1 +// gg64(uint64): 1 -> 1 +// f64(uint256): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE +// gg64(uint64): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE +// f64(uint256): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF +// gg64(uint64): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF +// f64(uint256): 0x010000000000000000 -> 0x0000000000000000 +// gg64(uint64): 0x010000000000000000 -> FAILURE +// f64(uint256): 0x010000000000000001 -> 0x0000000000000001 +// gg64(uint64): 0x010000000000000001 -> FAILURE +// f64(uint256): -1 -> 0xFFFFFFFFFFFFFFFF +// gg64(uint64): -1 -> FAILURE +// f128(uint256): 0 -> 0 +// g128(uint128): 0 -> 0 +// f128(uint256): 1 -> 1 +// g128(uint128): 1 -> 1 +// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// f128(uint256): 0x0100000000000000000000000000000000 -> 0x00000000000000000000000000000000 +// g128(uint128): 0x0100000000000000000000000000000000 -> FAILURE +// f128(uint256): 0x0100000000000000000000000000000001 -> 0x00000000000000000000000000000001 +// g128(uint128): 0x0100000000000000000000000000000001 -> FAILURE +// f128(uint256): -1 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// g128(uint128): -1 -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx_standard_input.json b/examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx_standard_input.json new file mode 100644 index 00000000..62f53890 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_cleanup_uintx/uintx_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "simple_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint8 a; bytes1 b; }\n function gg(S calldata s) external pure returns (bytes memory) {\n s.a; s.b; // only this will validate.\n return msg.data;\n }\n function f(uint256 a, bytes32 b) public returns (bytes memory) {\n S memory s = S(2,0x02);\n assembly {\n mstore(s, a)\n mstore(add(s, 0x20), b)\n }\n return this.gg(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256,bytes32): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 1, left(0x01) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// f(uint256,bytes32): 0x0101, left(0x0101) -> 0x20, 0x44, hex\"b63240b0\", 1, left(0x01), hex\"00000000000000000000000000000000000000000000000000000000\"\n// gg((uint8,bytes1)): 0x0101, left(0x0101) -> FAILURE\n" + }, + "bool.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gggg(bool x) external pure returns (bool) {\n return x;\n }\n function f(uint256 a) external view returns (bool) {\n bool x = false;\n assembly { x := a }\n return this.gggg(x);\n }\n}\n// ----\n// f(uint256): 0 -> false\n// gggg(bool): 0 -> false # test validation as well as sanity check #\n// f(uint256): 1 -> true\n// gggg(bool): 1 -> true\n// f(uint256): 2 -> true\n// gggg(bool): 2 -> FAILURE\n// f(uint256): 0x1000 -> true\n// gggg(bool): 0x1000 -> FAILURE\n" + }, + "intx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(int8 x) external pure returns (int256) {\n return x;\n }\n function gg16(int16 x) external pure returns (int256) {\n return x;\n }\n function gg32(int32 x) external pure returns (int256) {\n return x;\n }\n function gg64(int64 x) external pure returns (int256) {\n return x;\n }\n function g128(int128 x) external pure returns (int256) {\n return x;\n }\n function f8(int256 a) external view returns (int256) {\n int8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(int256 a) external view returns (int256) {\n int16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(int256 a) external view returns (int256) {\n int32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(int256 a) external view returns (int256) {\n int64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(int256 a) external view returns (int256) {\n int128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(int256): 0 -> 0\n// ggg8(int8): 0 -> 0 # test validation as well as sanity check #\n// f8(int256): 1 -> 1\n// ggg8(int8): 1 -> 1\n// f8(int256): -1 -> -1\n// ggg8(int8): -1 -> -1\n// f8(int256): 0x7F -> 0x7F\n// ggg8(int8): 0x7F -> 0x7F\n// f8(int256): 0x80 -> -128\n// ggg8(int8): 0x80 -> FAILURE\n// f8(int256): 0xFE -> -2\n// ggg8(int8): 0xFE -> FAILURE\n// f8(int256): 0xFF -> -1\n// ggg8(int8): 0xFF -> FAILURE\n// f8(int256): 0x0100 -> 0x00\n// ggg8(int8): 0x0100 -> FAILURE\n// f8(int256): 0x0101 -> 0x01\n// ggg8(int8): 0x0101 -> FAILURE\n// f8(int256): 0x01FF -> -1\n// ggg8(int8): 0x01FF -> FAILURE\n// f8(int256): 0x01FE -> -2\n// ggg8(int8): 0x01FE -> FAILURE\n// f16(int256): 0 -> 0\n// gg16(int16): 0 -> 0\n// f16(int256): 1 -> 1\n// gg16(int16): 1 -> 1\n// f16(int256): -1 -> -1\n// gg16(int16): -1 -> -1\n// f16(int256): 0x7FFF -> 0x7FFF\n// gg16(int16): 0x7FFF -> 0x7FFF\n// f16(int256): 0x8000 -> -32768\n// gg16(int16): 0x8000 -> FAILURE\n// f16(int256): 0xFFFE -> -2\n// gg16(int16): 0xFFFE -> FAILURE\n// f16(int256): 0xFFFF -> -1\n// gg16(int16): 0xFFFF -> FAILURE\n// f16(int256): 0x010000 -> 0x00\n// gg16(int16): 0x010000 -> FAILURE\n// f16(int256): 0x010001 -> 0x01\n// gg16(int16): 0x010001 -> FAILURE\n// f16(int256): 0x01FFFF -> -1\n// gg16(int16): 0x01FFFF -> FAILURE\n// f16(int256): 0x01FFFE -> -2\n// gg16(int16): 0x01FFFE -> FAILURE\n// f32(int256): 0 -> 0\n// gg32(int32): 0 -> 0\n// f32(int256): 1 -> 1\n// gg32(int32): 1 -> 1\n// f32(int256): -1 -> -1\n// gg32(int32): -1 -> -1\n// f32(int256): 0x7FFFFFFF -> 0x7FFFFFFF\n// gg32(int32): 0x7FFFFFFF -> 0x7FFFFFFF\n// f32(int256): 0x80000000 -> -2147483648\n// gg32(int32): 0x80000000 -> FAILURE\n// f32(int256): 0xFFFFFFFE -> -2\n// gg32(int32): 0xFFFFFFFE -> FAILURE\n// f32(int256): 0xFFFFFFFF -> -1\n// gg32(int32): 0xFFFFFFFF -> FAILURE\n// f32(int256): 0x0100000000 -> 0x00\n// gg32(int32): 0x0100000000 -> FAILURE\n// f32(int256): 0x0100000001 -> 0x01\n// gg32(int32): 0x0100000001 -> FAILURE\n// f32(int256): 0x01FFFFFFFF -> -1\n// gg32(int32): 0x01FFFFFFFF -> FAILURE\n// f32(int256): 0x01FFFFFFFE -> -2\n// gg32(int32): 0x01FFFFFFFE -> FAILURE\n// f64(int256): 0 -> 0\n// gg64(int64): 0 -> 0\n// f64(int256): 1 -> 1\n// gg64(int64): 1 -> 1\n// f64(int256): -1 -> -1\n// gg64(int64): -1 -> -1\n// f64(int256): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// gg64(int64): 0x7FFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFF\n// f64(int256): 0x8000000000000000 -> -9223372036854775808\n// gg64(int64): 0x8000000000000000 -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0xFFFFFFFFFFFFFFFE -> FAILURE\n// f64(int256): 0xFFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0xFFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x010000000000000000 -> 0x00\n// gg64(int64): 0x010000000000000000 -> FAILURE\n// f64(int256): 0x010000000000000001 -> 0x01\n// gg64(int64): 0x010000000000000001 -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFF -> -1\n// gg64(int64): 0x01FFFFFFFFFFFFFFFF -> FAILURE\n// f64(int256): 0x01FFFFFFFFFFFFFFFE -> -2\n// gg64(int64): 0x01FFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0 -> 0\n// g128(int128): 0 -> 0\n// f128(int256): 1 -> 1\n// g128(int128): 1 -> 1\n// f128(int256): -1 -> -1\n// g128(int128): -1 -> -1\n// f128(int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(int128): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(int256): 0x80000000000000000000000000000000 -> -170141183460469231731687303715884105728\n// g128(int128): 0x80000000000000000000000000000000 -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n// f128(int256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000000 -> 0x00\n// g128(int128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(int256): 0x0100000000000000000000000000000001 -> 0x01\n// g128(int128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE\n// f128(int256): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> -2\n// g128(int128): 0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> FAILURE\n" + }, + "bytesx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function gg1(bytes1 x) external pure returns (bytes32) {\n return x;\n }\n function f1(bytes32 a) external view returns (bytes32) {\n bytes1 x;\n assembly { x := a }\n return this.gg1(x);\n }\n function gg2(bytes2 x) external pure returns (bytes32) {\n return x;\n }\n function f2(bytes32 a) external view returns (bytes32) {\n bytes2 x;\n assembly { x := a }\n return this.gg2(x);\n }\n function gg4(bytes4 x) external pure returns (bytes32) {\n return x;\n }\n function f4(bytes32 a) external view returns (bytes32) {\n bytes4 x;\n assembly { x := a }\n return this.gg4(x);\n }\n function gg8(bytes8 x) external pure returns (bytes32) {\n return x;\n }\n function f8(bytes32 a) external view returns (bytes32) {\n bytes8 x;\n assembly { x := a }\n return this.gg8(x);\n }\n function g16(bytes16 x) external pure returns (bytes32) {\n return x;\n }\n function f16(bytes32 a) external view returns (bytes32) {\n bytes16 x;\n assembly { x := a }\n return this.g16(x);\n }\n}\n// ----\n// f1(bytes32): left(0) -> left(0)\n// gg1(bytes1): left(0) -> left(0) # test validation as well as sanity check #\n// f1(bytes32): left(1) -> left(1)\n// gg1(bytes1): left(1) -> left(1)\n// f1(bytes32): left(0xFE) -> left(0xFE)\n// gg1(bytes1): left(0xFE) -> left(0xFE)\n// f1(bytes32): left(0xFF) -> left(0xFF)\n// gg1(bytes1): left(0xFF) -> left(0xFF)\n// f1(bytes32): left(0x0001) -> left(0x00)\n// gg1(bytes1): left(0x0001) -> FAILURE\n// f1(bytes32): left(0x0101) -> left(0x01)\n// gg1(bytes1): left(0x0101) -> FAILURE\n// f1(bytes32): -1 -> left(0xFF)\n// gg1(bytes1): -1 -> FAILURE\n// f2(bytes32): left(0) -> left(0)\n// gg2(bytes2): left(0) -> left(0)\n// f2(bytes32): left(1) -> left(1)\n// gg2(bytes2): left(1) -> left(1)\n// f2(bytes32): left(0xFFFE) -> left(0xFFFE)\n// gg2(bytes2): left(0xFFFE) -> left(0xFFFE)\n// f2(bytes32): left(0xFFFF) -> left(0xFFFF)\n// gg2(bytes2): left(0xFFFF) -> left(0xFFFF)\n// f2(bytes32): left(0x000001) -> left(0x00)\n// gg2(bytes2): left(0x000001) -> FAILURE\n// f2(bytes32): left(0x010001) -> left(0x01)\n// gg2(bytes2): left(0x010001) -> FAILURE\n// f2(bytes32): -1 -> left(0xFFFF)\n// gg2(bytes2): -1 -> FAILURE\n// f4(bytes32): left(0) -> left(0)\n// gg4(bytes4): left(0) -> left(0)\n// f4(bytes32): left(1) -> left(1)\n// gg4(bytes4): left(1) -> left(1)\n// f4(bytes32): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// gg4(bytes4): left(0xFFFFFFFE) -> left(0xFFFFFFFE)\n// f4(bytes32): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// gg4(bytes4): left(0xFFFFFFFF) -> left(0xFFFFFFFF)\n// f4(bytes32): left(0x0000000001) -> left(0x00)\n// gg4(bytes4): left(0x0000000001) -> FAILURE\n// f4(bytes32): left(0x0100000001) -> left(0x01)\n// gg4(bytes4): left(0x0100000001) -> FAILURE\n// f4(bytes32): -1 -> left(0xFFFFFFFF)\n// gg4(bytes4): -1 -> FAILURE\n// f8(bytes32): left(0) -> left(0)\n// gg8(bytes8): left(0) -> left(0)\n// f8(bytes32): left(1) -> left(1)\n// gg8(bytes8): left(1) -> left(1)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFE)\n// f8(bytes32): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): left(0xFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFF)\n// f8(bytes32): left(0x000000000000000001) -> left(0x00)\n// gg8(bytes8): left(0x000000000000000001) -> FAILURE\n// f8(bytes32): left(0x010000000000000001) -> left(0x01)\n// gg8(bytes8): left(0x010000000000000001) -> FAILURE\n// f8(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFF)\n// gg8(bytes8): -1 -> FAILURE\n// f16(bytes32): left(0) -> left(0)\n// g16(bytes16): left(0) -> left(0)\n// f16(bytes32): left(1) -> left(1)\n// g16(bytes16): left(1) -> left(1)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE)\n// f16(bytes32): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// f16(bytes32): left(0x0000000000000000000000000000000001) -> left(0x00)\n// g16(bytes16): left(0x0000000000000000000000000000000001) -> FAILURE\n// f16(bytes32): left(0x0100000000000000000000000000000001) -> left(0x01)\n// g16(bytes16): left(0x0100000000000000000000000000000001) -> FAILURE\n// f16(bytes32): -1 -> left(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n// g16(bytes16): -1 -> FAILURE\n" + }, + "address.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(address x) external pure returns (uint256 r) {\n assembly { r := x }\n }\n function f(uint256 a) external view returns (uint256) {\n address x;\n assembly { x := a }\n return this.g(x);\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// g(address): 0 -> 0 # test validation as well as sanity check #\n// f(uint256): 1 -> 1\n// g(address): 1 -> 1\n// f(uint256): 2 -> 2\n// g(address): 2 -> 2\n// f(uint256): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0xabcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// f(uint256): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// f(uint256): 0x010000000000000000000000000000000000000000 -> 0\n// g(address): 0x010000000000000000000000000000000000000000 -> FAILURE\n// f(uint256): 0x01abcdef0123456789abcdef0123456789abcdefff -> 0xabcdef0123456789abcdef0123456789abcdefff\n// g(address): 0x01abcdef0123456789abcdef0123456789abcdefff -> FAILURE\n// f(uint256): 0x01ffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): 0x01ffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// f(uint256): -1 -> 0xffffffffffffffffffffffffffffffffffffffff\n// g(address): -1 -> FAILURE\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint16 a, int16 b, address c, bytes3 d, bool e)\n public pure returns (uint v, uint w, uint x, uint y, uint z) {\n assembly { v := a w := b x := c y := d z := e}\n }\n}\n// ----\n// f(uint16,int16,address,bytes3,bool): 1, 2, 3, \"a\", true -> 1, 2, 3, \"a\", true\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0x1ffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0xffffff, 0, 0, \"bcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0x1ffff, 0, \"ab\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, \"ad\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abcd\", 1 -> FAILURE\n// f(uint16,int16,address,bytes3,bool): 0, 0, 0, \"abc\", 2 -> FAILURE\n" + }, + "function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function() external f; }\n function ggg(function() external x) external pure returns (uint256 r) {\n assembly { r := calldataload(4) }\n }\n function h(S calldata x) external pure returns (uint256 r) {\n x.f; // validation only happens here\n assembly { r := calldataload(4) }\n }\n function dummy() external {}\n function ffff(uint256 a) external view returns (uint256, uint256) {\n S memory s = S(this.dummy);\n assembly { mstore(s, a) }\n return (this.ggg(s.f), this.h(s));\n }\n}\n// ----\n// ffff(uint256): 0 -> 0, 0\n// ggg(function): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): \"01234567890123456789abcd\" -> \"01234567890123456789abcd\"\n// h((function)): 0 -> 0\n// ffff(uint256): \"01234567890123456789abcdX\" -> \"01234567890123456789abcd\", \"01234567890123456789abcd\"\n// ggg(function): \"01234567890123456789abcdX\" -> FAILURE\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + }, + "uintx.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function ggg8(uint8 x) external pure returns (uint256) {\n return x;\n }\n function gg16(uint16 x) external pure returns (uint256) {\n return x;\n }\n function gg32(uint32 x) external pure returns (uint256) {\n return x;\n }\n function gg64(uint64 x) external pure returns (uint256) {\n return x;\n }\n function g128(uint128 x) external pure returns (uint256) {\n return x;\n }\n function f8(uint256 a) external view returns (uint256) {\n uint8 x = 0;\n assembly { x := a }\n return this.ggg8(x);\n }\n function f16(uint256 a) external view returns (uint256) {\n uint16 x = 0;\n assembly { x := a }\n return this.gg16(x);\n }\n function f32(uint256 a) external view returns (uint256) {\n uint32 x = 0;\n assembly { x := a }\n return this.gg32(x);\n }\n function f64(uint256 a) external view returns (uint256) {\n uint64 x = 0;\n assembly { x := a }\n return this.gg64(x);\n }\n function f128(uint256 a) external view returns (uint256) {\n uint128 x = 0;\n assembly { x := a }\n return this.g128(x);\n }\n}\n// ----\n// f8(uint256): 0 -> 0\n// ggg8(uint8): 0 -> 0 # test validation as well as sanity check #\n// f8(uint256): 1 -> 1\n// ggg8(uint8): 1 -> 1\n// f8(uint256): 0xFE -> 0xFE\n// ggg8(uint8): 0xFE -> 0xFE\n// f8(uint256): 0xFF -> 0xFF\n// ggg8(uint8): 0xFF -> 0xFF\n// f8(uint256): 0x0100 -> 0x00\n// ggg8(uint8): 0x0100 -> FAILURE\n// f8(uint256): 0x0101 -> 0x01\n// ggg8(uint8): 0x0101 -> FAILURE\n// f8(uint256): -1 -> 0xFF\n// ggg8(uint8): -1 -> FAILURE\n// f16(uint256): 0 -> 0\n// gg16(uint16): 0 -> 0\n// f16(uint256): 1 -> 1\n// gg16(uint16): 1 -> 1\n// f16(uint256): 0xFFFE -> 0xFFFE\n// gg16(uint16): 0xFFFE -> 0xFFFE\n// f16(uint256): 0xFFFF -> 0xFFFF\n// gg16(uint16): 0xFFFF -> 0xFFFF\n// f16(uint256): 0x010000 -> 0x0000\n// gg16(uint16): 0x010000 -> FAILURE\n// f16(uint256): 0x010001 -> 0x0001\n// gg16(uint16): 0x010001 -> FAILURE\n// f16(uint256): -1 -> 0xFFFF\n// gg16(uint16): -1 -> FAILURE\n// f32(uint256): 0 -> 0\n// gg32(uint32): 0 -> 0\n// f32(uint256): 1 -> 1\n// gg32(uint32): 1 -> 1\n// f32(uint256): 0xFFFFFFFE -> 0xFFFFFFFE\n// gg32(uint32): 0xFFFFFFFE -> 0xFFFFFFFE\n// f32(uint256): 0xFFFFFFFF -> 0xFFFFFFFF\n// gg32(uint32): 0xFFFFFFFF -> 0xFFFFFFFF\n// f32(uint256): 0x0100000000 -> 0x00000000\n// gg32(uint32): 0x0100000000 -> FAILURE\n// f32(uint256): 0x0100000001 -> 0x00000001\n// gg32(uint32): 0x0100000001 -> FAILURE\n// f32(uint256): -1 -> 0xFFFFFFFF\n// gg32(uint32): -1 -> FAILURE\n// f64(uint256): 0 -> 0\n// gg64(uint64): 0 -> 0\n// f64(uint256): 1 -> 1\n// gg64(uint64): 1 -> 1\n// f64(uint256): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// gg64(uint64): 0xFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFE\n// f64(uint256): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): 0xFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFF\n// f64(uint256): 0x010000000000000000 -> 0x0000000000000000\n// gg64(uint64): 0x010000000000000000 -> FAILURE\n// f64(uint256): 0x010000000000000001 -> 0x0000000000000001\n// gg64(uint64): 0x010000000000000001 -> FAILURE\n// f64(uint256): -1 -> 0xFFFFFFFFFFFFFFFF\n// gg64(uint64): -1 -> FAILURE\n// f128(uint256): 0 -> 0\n// g128(uint128): 0 -> 0\n// f128(uint256): 1 -> 1\n// g128(uint128): 1 -> 1\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f128(uint256): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f128(uint256): 0x0100000000000000000000000000000000 -> 0x00000000000000000000000000000000\n// g128(uint128): 0x0100000000000000000000000000000000 -> FAILURE\n// f128(uint256): 0x0100000000000000000000000000000001 -> 0x00000000000000000000000000000001\n// g128(uint128): 0x0100000000000000000000000000000001 -> FAILURE\n// f128(uint256): -1 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// g128(uint128): -1 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays.sol b/examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays.sol new file mode 100644 index 00000000..e8b64a10 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays.sol @@ -0,0 +1,10 @@ +pragma abicoder v2; + +contract C { + function f(uint a, uint16[] memory b, uint c) + public pure returns (uint, uint, uint) { + return (b.length, b[a], c); + } +} +// ---- +// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9 diff --git a/examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays_standard_input.json new file mode 100644 index 00000000..b09c92bb --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_dynamic_arrays/dynamic_arrays_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays.sol b/examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays.sol new file mode 100644 index 00000000..e9816ef1 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays.sol @@ -0,0 +1,30 @@ +pragma abicoder v2; + +contract C { + function f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d) + public pure returns (uint, uint, uint, uint, uint, uint, uint) { + return (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d); + } + function test() public view returns (uint, uint, uint, uint, uint, uint, uint) { + uint16[][] memory b = new uint16[][](3); + b[0] = new uint16[](2); + b[0][0] = 0x55; + b[0][1] = 0x56; + b[1] = new uint16[](4); + b[1][0] = 0x65; + b[1][1] = 0x66; + b[1][2] = 0x67; + b[1][3] = 0x68; + + uint[2][][3] memory c; + c[0] = new uint[2][](1); + c[0][0][1] = 0x75; + c[1] = new uint[2][](5); + c[1][1][1] = 0x85; + + return this.f(12, b, c, 13); + } +} +// ---- +// test() -> 12, 3, 4, 0x66, 5, 0x85, 13 +// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13 diff --git a/examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays_standard_input.json b/examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays_standard_input.json new file mode 100644 index 00000000..603b8063 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_dynamic_nested_arrays/dynamic_nested_arrays_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + }, + "dynamic_nested_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)\n\t\t\tpublic pure returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\treturn (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);\n\t}\n\tfunction test() public view returns (uint, uint, uint, uint, uint, uint, uint) {\n\t\tuint16[][] memory b = new uint16[][](3);\n\t\tb[0] = new uint16[](2);\n\t\tb[0][0] = 0x55;\n\t\tb[0][1] = 0x56;\n\t\tb[1] = new uint16[](4);\n\t\tb[1][0] = 0x65;\n\t\tb[1][1] = 0x66;\n\t\tb[1][2] = 0x67;\n\t\tb[1][3] = 0x68;\n\n\t\tuint[2][][3] memory c;\n\t\tc[0] = new uint[2][](1);\n\t\tc[0][0][1] = 0x75;\n\t\tc[1] = new uint[2][](5);\n\t\tc[1][1][1] = 0x85;\n\n\t\treturn this.f(12, b, c, 13);\n\t}\n}\n// ----\n// test() -> 12, 3, 4, 0x66, 5, 0x85, 13\n// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_enums/enums.sol b/examples/test/semanticTests/abiEncoderV2_enums/enums.sol new file mode 100644 index 00000000..1e323472 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_enums/enums.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; + +contract C { + enum E { A, B } + function f(E e) public pure returns (uint x) { + assembly { x := e } + } +} +// ---- +// f(uint8): 0 -> 0 +// f(uint8): 1 -> 1 +// f(uint8): 2 -> FAILURE +// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_enums/enums_standard_input.json b/examples/test/semanticTests/abiEncoderV2_enums/enums_standard_input.json new file mode 100644 index 00000000..15e94e34 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_enums/enums_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol new file mode 100644 index 00000000..3fe54eff --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes.sol @@ -0,0 +1,12 @@ +contract C { + function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) { + return f(a, b); + } +} +// ---- +// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, "123456" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, "123456" +// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, "12345678" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, "12345678" diff --git a/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json new file mode 100644 index 00000000..0017547e --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_bytes/memory_dynamic_array_and_calldata_bytes_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + }, + "memory_dynamic_array_and_calldata_bytes.sol": { + "content": "contract C {\n function f(uint256[] memory a, bytes calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, bytes calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n}\n// ----\n// f(uint256[],bytes): 0x40, 0x80, 1, 0xFF, 6, \"123456\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xff, 6, \"123456\"\n// g(uint256[],bytes): 0x40, 0x80, 1, 0xffff, 8, \"12345678\" -> 0x20, 0xc0, 0x40, 0x80, 1, 0xffff, 8, \"12345678\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array.sol b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array.sol new file mode 100644 index 00000000..a734103f --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array.sol @@ -0,0 +1,17 @@ +contract C { + function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) { + return abi.encode(a, b); + } + + function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) { + return f(a, b); + } + + function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) { + return (a, b); + } +} +// ---- +// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff +// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff +// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff diff --git a/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array_standard_input.json b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array_standard_input.json new file mode 100644 index 00000000..6a261338 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_memory_dynamic_array_and_calldata_static_array/memory_dynamic_array_and_calldata_static_array_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function.sol b/examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function.sol new file mode 100644 index 00000000..f8beb570 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + +contract C { + function f(bytes memory a, bytes calldata b, uint[] memory c) + external + pure + returns (uint, bytes1, uint, bytes1, uint, uint) + { + return (a.length, a[1], b.length, b[2], c.length, c[3]); + } + function g() public returns (uint, bytes1, uint, bytes1, uint, uint) { + uint[] memory x = new uint[](4); + x[3] = 7; + return this.f("abc", "def", x); + } +} +// ---- +// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7 diff --git a/examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function_standard_input.json b/examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function_standard_input.json new file mode 100644 index 00000000..06b29032 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_memory_params_in_external_function/memory_params_in_external_function_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding.sol b/examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding.sol new file mode 100644 index 00000000..9599af6c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding.sol @@ -0,0 +1,27 @@ +pragma abicoder v2; + +// tests encoding from storage arrays + +contract C { + uint256[2][] tmp_h; + function h(uint256[2][] calldata s) external returns (bytes memory) { + tmp_h = s; + return abi.encode(tmp_h); + } + uint256[2][2] tmp_i; + function i(uint256[2][2] calldata s) external returns (bytes memory) { + tmp_i = s; + return abi.encode(tmp_i); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 +// gas irOptimized: 180080 +// gas legacy: 184233 +// gas legacyOptimized: 180856 +// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 +// gas irOptimized: 112031 +// gas legacy: 115091 +// gas legacyOptimized: 112657 diff --git a/examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding_standard_input.json b/examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding_standard_input.json new file mode 100644 index 00000000..d48afec4 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_storage_array_encoding/storage_array_encoding_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_array_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct D { uint[] x; }\n struct S { uint x; }\n\n function f(D calldata a) public returns (bytes memory){\n return abi.encode(a);\n }\n\n function g(D[2] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function h(D[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function i(D[2][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function j(S[] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function k(S[2] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function l(S[][] memory a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n}\n// ----\n// f((uint256[])): 0x20, 0x20, 0 -> 0x20, 0x60, 0x20, 0x20, 0\n// f((uint256[])): 0x20, 0x20, 1 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 2 -> FAILURE\n// f((uint256[])): 0x20, 0x20, 3 -> FAILURE\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0140, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// g((uint256[])[2]): 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1 -> 0x20, 0x0260, 0x20, 2, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1, 1\n// h((uint256[])[][]): 0x20, 0x02, 0x40, 0x0180, 2, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3, 1, 0x20, 0x20, 1 -> FAILURE\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3 -> 0x20, 0x0180, 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1, 3\n// i((uint256[])[2][]): 0x20, 1, 0x20, 0x40, 0xc0, 0x20, 2, 1, 2, 0x20, 1 -> FAILURE\n// j((uint256)[]): 0x20, 2, 1, 2 -> 0x20, 0x80, 0x20, 2, 1, 2\n// j((uint256)[]): 0x20, 2, 1 -> FAILURE\n// k((uint256)[2]): 1, 2 -> 0x20, 0x40, 1, 2\n// k((uint256)[2]): 1 -> FAILURE\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9, 10 -> 0x20, 0x0160, 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8, 9\n// l((uint256)[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n" + }, + "abi_encode_rational_v2.sol": { + "content": "// Tests that rational numbers (even negative ones) are encoded properly.\npragma abicoder v2;\n\n\ncontract C {\n function f() public pure returns (bytes memory) {\n return abi.encode(1, -2);\n }\n}\n// ----\n// f() -> 0x20, 0x40, 0x1, -2\n" + }, + "dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, uint16[] memory b, uint c)\n public pure returns (uint, uint, uint) {\n return (b.length, b[a], c);\n }\n}\n// ----\n// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9\n" + }, + "calldata_nested_array_static_reencode.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[3][] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[][3] calldata a) public {\n\t\tabi.encode(a);\n\t}\n\tfunction f(uint[2][2] calldata a) public {\n\t\tabi.encode(a);\n\t}\n}\n// ----\n// f(uint256[3][]): 0x20, 1, 0x01 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02 -> FAILURE\n// f(uint256[3][]): 0x20, 1, 0x01, 0x02, 0x03 ->\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02 -> FAILURE\n// f(uint256[][3]): 0x20, 0x60, 0x60, 0x60, 3, 0x01, 0x02, 0x03 ->\n// f(uint256[2][2]): 0x01 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03 -> FAILURE\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04 ->\n// f(uint256[2][2]): 0x01, 0x02, 0x03, 0x04, 0x05 ->\n" + }, + "byte_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint a, bytes memory b, uint c)\n public pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n\n function f_external(uint a, bytes calldata b, uint c)\n external pure returns (uint, uint, bytes1, uint) {\n return (a, b.length, b[3], c);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, \"abcdefg\" -> 6, 7, \"d\", 9\n" + }, + "calldata_struct_member_offset.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct A {\n uint256 a;\n uint256[] b;\n }\n struct B {\n A a;\n uint256 b;\n }\n function g(B calldata b) external pure returns(uint256) {\n return b.b;\n }\n function f() public view returns(uint256, uint256) {\n uint256[] memory arr = new uint256[](20);\n arr[0] = 31; arr[2] = 84;\n B memory b = B(A(420, arr), 11);\n return (b.b, this.g(b));\n }\n}\n// ----\n// f() -> 11, 11\n" + }, + "calldata_with_garbage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] aTmp;\n uint[2] bTmp;\n\n function f_memory(uint[] calldata a) public returns (uint[] memory) {\n return a;\n }\n\n function f_encode(uint[] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_storage(uint[] calldata a) public returns (bytes memory) {\n aTmp = a;\n return abi.encode(aTmp);\n }\n\n function f_index(uint[] calldata a, uint which) public returns (uint) {\n return a[which];\n }\n\n function g_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function g_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g_storage(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n aTmp = a;\n bTmp = b;\n return abi.encode(aTmp, bTmp);\n }\n\n function g_index(uint[] calldata a, uint[2] calldata b, uint which) public returns (uint, uint) {\n return (a[which], b[0]);\n }\n}\n// ----\n// f_memory(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0\n// f_memory(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 1, 7\n// f_memory(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_encode(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_encode(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_encode(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_storage(uint256[]): 0x80, 9, 9, 9, 0 -> 0x20, 0x40, 0x20, 0\n// f_storage(uint256[]): 0x80, 9, 9, 9, 1, 7 -> 0x20, 0x60, 0x20, 1, 7\n// f_storage(uint256[]): 0x80, 9, 9, 9, 2, 7 -> FAILURE\n// f_index(uint256[],uint256): 0xa0, 0, 9, 9, 9, 2, 7, 8 -> 7\n// f_index(uint256[],uint256): 0xa0, 1, 9, 9, 9, 2, 7, 8 -> 8\n// f_index(uint256[],uint256): 0xa0, 2, 9, 9, 9, 2, 7, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x60, 1, 2, 0\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x60, 1, 2, 1, 7\n// g_memory(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_encode(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 0 -> 0x20, 0x80, 0x60, 1, 2, 0\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 1, 7 -> 0x20, 0xa0, 0x60, 1, 2, 1, 7\n// g_storage(uint256[],uint256[2]): 0xc0, 1, 2, 9, 9, 9, 2, 7 -> FAILURE\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 0, 9, 9, 9, 2, 7, 8 -> 7, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7, 8 -> 8, 1\n// g_index(uint256[],uint256[2],uint256): 0xe0, 1, 2, 1, 9, 9, 9, 2, 7 -> FAILURE\n" + }, + "calldata_array_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n function f(S[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(S[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n// g((uint256[])[]): 32, 1, 32, 32, 3, 17, 42, 23 -> 32, 256, 32, 1, 32, 32, 3, 17, 42, 23\n" + }, + "calldata_array_short_no_revert_string.sol": { + "content": "contract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE\n// f(uint256[]): 0x20, 2 -> FAILURE\n\n" + }, + "calldata_array_dynamic_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes[2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.j(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// g(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// h(uint8[]): 32, 3, 42, 23, 87 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17 -> 32, 160, 32, 3, 42, 23, 87\n// i(uint8[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 42, 23, 87, 4, 11, 13, 17, 27 -> 32, 192, 32, 4, 11, 13, 17, 27\n// j(bytes): 32, 3, hex\"AB11FF\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 0, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 3, left(0xAB11FF)\n// k(bytes[2],uint256): 0x40, 1, 0x40, 0x63, 3, hex\"AB11FF\", 4, hex\"FF791432\" -> 32, 96, 32, 4, left(0xFF791432)\n" + }, + "calldata_overlapped_nested_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function f_encode(uint[][] calldata a) public returns (bytes memory) {\n return abi.encode(a);\n }\n\n function f_which(uint[][] calldata a, uint which) public returns (uint[] memory) {\n return a[which];\n }\n}\n// ----\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_memory(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x0140, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 0x0120, 0x20, 2, 0x40, 0xa0, 2, 1, 2, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0xe0, 0x20, 2, 0x40, 0x60, 0, 1, 2\n// f_encode(uint256[][]): 0x20, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x40, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 2, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0x40, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 0, 2, 0, 0x60, 2, 1, 2 -> 0x20, 0\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 1, 2 -> 0x20, 1, 2\n// f_which(uint256[][],uint256): 0x40, 1, 2, 0, 0x60, 2, 2, 2 -> FAILURE\n" + }, + "memory_params_in_external_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes memory a, bytes calldata b, uint[] memory c)\n external\n pure\n returns (uint, bytes1, uint, bytes1, uint, uint)\n {\n return (a.length, a[1], b.length, b[2], c.length, c[3]);\n }\n function g() public returns (uint, bytes1, uint, bytes1, uint, uint) {\n uint[] memory x = new uint[](4);\n x[3] = 7;\n return this.f(\"abc\", \"def\", x);\n }\n}\n// ----\n// g() -> 3, 0x6200000000000000000000000000000000000000000000000000000000000000, 3, 0x6600000000000000000000000000000000000000000000000000000000000000, 4, 7\n" + }, + "calldata_array_dynamic_static_in_library.sol": { + "content": "library L {\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function g(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] calldata) {\n return (a, b);\n }\n}\n\ncontract C {\n function f(uint[] memory a, uint[1] calldata b) public returns (uint[] memory, uint[1] memory) {\n return L.g(a, b);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 0x01, 0xffff\n" + }, + "bool_out_of_bounds.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(bool b) public pure returns (bool) { return b; }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> false\n// f(bool): 0x000000 -> false\n// f(bool): 0xffffff -> FAILURE\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint[][] calldata a) public returns (uint[][] memory) {\n return a;\n }\n\n function g(uint[][][] calldata a) public returns (uint[][][] memory) {\n return a;\n }\n\n function h(uint[2][][] calldata a) public returns (uint[2][][] memory) {\n return a;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8, 9 -> 0x20, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 5, 6, 3, 7, 8 -> FAILURE\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7, 8\n// g(uint256[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0xa0, 2, 5, 6, 2, 7 -> FAILURE\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8, 9 -> 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7, 8\n// h(uint256[2][][]): 0x20, 2, 0x40, 0x60, 0, 2, 5, 6, 7 -> FAILURE\n" + }, + "calldata_array_two_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[3] calldata s1, uint256[2] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// f(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, true -> 32, 96, 23, 42, 87\n// g(uint256[3],uint256[2],bool): 23, 42, 87, 51, 72, false -> 32, 64, 51, 72\n" + }, + "calldata_struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256 a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256)): 3 -> 32, 32, 3\n// g((uint256)): 3 -> 32, 32, 3\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0]; // trigger bounds checks\n return 23;\n }\n}\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x40, 0x60, 0x00, 0x00 -> 23 # this is the common encoding for x.length == 1 && x[0][0].length == 0 && x[0][1].length == 0 #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00, 0x00 -> 23 # exotic, but still valid encoding #\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE # invalid (too short) encoding, but no failure due to this PR #\n" + }, + "calldata_array_dynamic_static_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[][1][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[][2][] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[][1][] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[][2][] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[][1][] memory m = new uint8[][1][](1);\n m[0][0] = new uint8[](1);\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[][2][] memory m = new uint256[][2][](1);\n m[0][0] = new uint256[](1);\n m[0][1] = new uint256[](1);\n m[0][0][0] = 42;\n m[0][1][0] = 42;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 196, hex\"eccb829a\", 32, 1, 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "enums.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum E { A, B }\n function f(E e) public pure returns (uint x) {\n assembly { x := e }\n }\n}\n// ----\n// f(uint8): 0 -> 0\n// f(uint8): 1 -> 1\n// f(uint8): 2 -> FAILURE\n// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_array_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint[] calldata) public {}\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 0 ->\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n// f(uint256[]): 0x20, 2 -> FAILURE, hex\"08c379a0\", 0x20, 0x2b, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_overlapped_dynamic_arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint[] s;\n uint[2] n;\n\n function f_memory(uint[] calldata a, uint[2] calldata b) public returns (uint[] memory, uint[2] memory) {\n return (a, b);\n }\n\n function f_encode(uint[] calldata a, uint[2] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function f_which(uint[] calldata a, uint[2] calldata b, uint which) public returns (bytes memory) {\n return abi.encode(a[which], b[1]);\n }\n\n function f_storage(uint[] calldata a, uint[2] calldata b ) public returns (bytes memory) {\n s = a;\n n = b;\n return abi.encode(s);\n }\n}\n// ----\n// f_memory(uint256[],uint256[2]): 0x20, 1, 2 -> 0x60, 0x01, 0x02, 1, 2\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x60, 1, 2, 2, 5, 6\n// f_memory(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_encode(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0xa0, 0x60, 1, 2, 1, 2\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0xc0, 0x60, 1, 2, 2, 5, 6\n// f_encode(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1, 5, 6 -> 0x20, 0x40, 5, 2\n// f_which(uint256[],uint256[2],uint256): 0x40, 1, 2, 1 -> FAILURE\n// f_storage(uint256[],uint256[2]): 0x20, 1, 2 -> 0x20, 0x60, 0x20, 1, 2\n// gas irOptimized: 111409\n// gas legacy: 112707\n// gas legacyOptimized: 111845\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5, 6 -> 0x20, 0x80, 0x20, 2, 5, 6\n// f_storage(uint256[],uint256[2]): 0x40, 1, 2, 5 -> FAILURE\n" + }, + "calldata_array_static_dynamic_static.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint8[1][][1] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function f2(uint256[2][][2] calldata s) external pure returns (bytes memory) {\n return msg.data;\n }\n function reenc_f(uint8[1][][1] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function reenc_f2(uint256[2][][2] calldata s) external view returns (bytes memory) {\n return this.f2(s);\n }\n function g() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.f(m);\n }\n function h() external returns (bytes memory) {\n uint8[1][][1] memory m = [new uint8[1][](1)];\n m[0][0][0] = 42;\n return this.reenc_f(m);\n }\n function i() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.f2(m);\n }\n function j() external returns (bytes memory) {\n uint256[2][][2] memory m = [new uint256[2][](1),new uint256[2][](1)];\n m[0][0][0] = 0x00042;\n m[0][0][1] = 0x00142;\n m[1][0][0] = 0x10042;\n m[1][0][1] = 0x10142;\n return this.reenc_f2(m);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// g() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// h() -> 32, 132, hex\"15cfcc01\", 32, 32, 1, 42, hex\"00000000000000000000000000000000000000000000000000000000\"\n// i() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n// j() -> 32, 292, hex\"dc0ee233\", 32, 64, 160, 1, 0x42, 0x000142, 1, 0x010042, 0x010142, hex\"00000000000000000000000000000000000000000000000000000000\"\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint256[] calldata) external pure returns (bytes memory) {\n return msg.data;\n }\n function f(uint256[][1] calldata s) external view returns (bool) {\n bytes memory a = this.g(s[0]);\n uint256[] memory m = s[0];\n bytes memory b = this.g(m);\n assert(a.length == b.length);\n for (uint i = 0; i < a.length; i++)\n assert(a[i] == b[i]);\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[][1]): 32, 32, 0 -> true\n// f(uint256[][1]): 32, 32, 1, 42 -> true\n// f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true\n// gas irOptimized: 120978\n// gas legacy: 101568\n// gas legacyOptimized: 119092\n" + }, + "calldata_three_dimensional_dynamic_array_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint[] a; }\n\n function f(uint[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j]);\n }\n\n function g(uint[][][] calldata s, uint i, uint j, uint k) public pure returns (bytes memory) {\n return abi.encode(s[i][j][k]);\n }\n\n function h(uint[][][1] calldata s, uint i) public pure returns (bytes memory) {\n return abi.encode(s[0][i]);\n }\n\n function k(S[][] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n\n function l(S[2][2] calldata s, uint i, uint j) public pure returns (bytes memory) {\n return abi.encode(s[i][j].a);\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 7\n// f(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0x80, 1, 7, 1, 8 -> 0x20, 0x20, 8\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 0, 0, 0, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 4\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> 0x20, 0x20, 6\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 1, 0, 2, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[][][],uint256,uint256,uint256): 0x80, 2, 0, 1, 2, 0x40, 0xc0, 1, 0x20, 1, 4, 2, 0x40, 0xa0, 2, 5, 6, 1, 7 -> FAILURE, hex\"4e487b71\", 0x32\n// h(uint256[][][1],uint256): 0x40, 1, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> 0x20, 0xa0, 0x20, 3, 7, 8, 9\n// h(uint256[][][1],uint256): 0x40, 2, 0x20, 2, 0x40, 0xA0, 2, 5, 6, 3, 7, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x60, 0x20, 1, 6\n// k((uint256[])[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xe0, 1, 0x20, 0x20, 1, 6, 2, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 1, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> 0x20, 0x80, 0x20, 2, 8, 9\n// l((uint256[])[2][2],uint256,uint256): 0x60, 1, 2, 0x40, 0x0140, 0x40, 0xa0, 0x20, 1, 5, 0x20, 1, 6, 0x40, 0xa0, 0x20, 1, 7, 0x20, 2, 8, 9 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "abi_encode_v2_in_function_inherited_in_v1_contract.sol": { + "content": "==== Source: A ====\npragma abicoder v2;\n\nstruct Data {\n uint a;\n uint[2] b;\n uint c;\n}\n\ncontract A {\n function get() public view returns (Data memory) {\n return Data(5, [uint(66), 77], 8);\n }\n}\n\ncontract B {\n function foo(A _a) public returns (uint) {\n return _a.get().b[1];\n }\n}\n==== Source: B ====\npragma abicoder v1;\n\nimport \"A\";\n\ncontract C is B {\n function test() public returns (uint) {\n return foo(new A());\n }\n}\n// ----\n// test() -> 77\n// gas irOptimized: 55117\n// gas irOptimized code: 56800\n// gas legacy: 57266\n// gas legacy code: 94600\n// gas legacyOptimized: 55195\n// gas legacyOptimized code: 55000\n" + }, + "calldata_struct_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint256[] a; }\n\n function f(S calldata s) external returns (bytes memory) {\n return abi.encode(s);\n }\n\n function g(S calldata s) external returns (bytes memory) {\n return this.f(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n// g((uint256[])): 0x20, 0x20, 3, 42, 23, 17 -> 32, 192, 0x20, 0x20, 3, 42, 23, 17\n" + }, + "calldata_array_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[] calldata s) external view returns (bytes memory) {\n return this.f(s);\n }\n function h(uint8[] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[] calldata s) external view returns (bytes memory) {\n return this.h(s);\n }\n function j(bytes calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function k(bytes calldata s) external view returns (bytes memory) {\n return this.j(s);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// g(uint256[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// i(uint8[]): 32, 3, 23, 42, 87 -> 32, 160, 32, 3, 23, 42, 87\n// h(uint8[]): 32, 3, 0xFF23, 0x1242, 0xAB87 -> FAILURE\n// i(uint8[]): 32, 3, 0xAB23, 0x1242, 0xFF87 -> FAILURE\n// j(bytes): 32, 3, hex\"123456\" -> 32, 96, 32, 3, left(0x123456)\n// k(bytes): 32, 3, hex\"AB33FF\" -> 32, 96, 32, 3, left(0xAB33FF)\n" + }, + "memory_dynamic_array_and_calldata_static_array.sol": { + "content": "contract C {\n function f(uint256[] memory a, uint256[1] calldata b) public returns (bytes memory) {\n return abi.encode(a, b);\n }\n\n function g(uint256[] memory a, uint256[1] calldata b) external returns (bytes memory) {\n return f(a, b);\n }\n\n function h(uint256[] memory a, uint256[1] calldata b) external returns (uint256[] memory, uint256[1] calldata) {\n return (a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// g(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x20, 0x80, 0x40, 0xff, 1, 0xffff\n// h(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> 0x40, 0xff, 1, 0xffff\n" + }, + "abi_encode_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[] b;\n }\n\n function f0() public pure returns (bytes memory) {\n return abi.encode();\n }\n\n function f1() public pure returns (bytes memory) {\n return abi.encode(1, 2);\n }\n\n function f2() public pure returns (bytes memory) {\n string memory x = \"abc\";\n return abi.encode(1, x, 2);\n }\n\n function f3() public pure returns (bytes memory r) {\n // test that memory is properly allocated\n string memory x = \"abc\";\n r = abi.encode(1, x, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n\n S s;\n\n function f4() public returns (bytes memory r) {\n string memory x = \"abc\";\n s.a = 7;\n s.b.push(2);\n s.b.push(3);\n r = abi.encode(1, x, s, 2);\n bytes memory y = \"def\";\n require(y[0] == \"d\");\n y[0] = \"e\";\n require(y[0] == \"e\");\n }\n}\n// ----\n// f0() -> 0x20, 0x0\n// f1() -> 0x20, 0x40, 0x1, 0x2\n// f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, \"abc\"\n// f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, \"abc\", 0x7, 0x40, 0x2, 0x2, 0x3\n// gas irOptimized: 111816\n// gas legacy: 113890\n// gas legacyOptimized: 111658\n" + }, + "calldata_array_two_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[] calldata s1, uint256[] calldata s2, bool which) external pure returns (bytes memory) {\n if (which)\n return abi.encode(s1);\n else\n return abi.encode(s2);\n }\n function g(uint256[] calldata s1, uint256[] calldata s2, bool which) external view returns (bytes memory) {\n return this.f(s1, s2, which);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// f(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n// g(uint256[],uint256[],bool): 0x60, 0xE0, true, 3, 23, 42, 87, 2, 51, 72 -> 32, 160, 0x20, 3, 23, 42, 87\n// g(uint256[],uint256[],bool): 0x60, 0xE0, false, 3, 23, 42, 87, 2, 51, 72 -> 32, 128, 0x20, 2, 51, 72\n" + }, + "calldata_array_static_index_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(uint256[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function g(uint256[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.f(s[which]);\n }\n function h(uint8[3] calldata s) external pure returns (bytes memory) {\n return abi.encode(s);\n }\n function i(uint8[3][2] calldata s, uint256 which) external view returns (bytes memory) {\n return this.h(s[which]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// g(uint256[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n// h(uint8[3]): 23, 42, 87 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 0 -> 32, 96, 23, 42, 87\n// i(uint8[3][2],uint256): 23, 42, 87, 123, 142, 187, 1 -> 32, 96, 123, 142, 187\n" + }, + "calldata_array_function_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n assert(s.length == 3);\n return (s[0](), s[1](), s[2]());\n }\n function f_reenc(function() external returns (uint)[] calldata s) external returns (uint, uint, uint) {\n return this.f(s);\n }\n function getter1() external returns (uint) {\n return 23;\n }\n function getter2() external returns (uint) {\n return 37;\n }\n function getter3() external returns (uint) {\n return 71;\n }\n function g(bool reenc) external returns (uint, uint, uint) {\n function() external returns (uint)[] memory a = new function() external returns (uint)[](3);\n a[0] = this.getter1;\n a[1] = this.getter2;\n a[2] = this.getter3;\n return reenc ? this.f_reenc(a) : this.f(a);\n }\n}\n// ----\n// g(bool): false -> 23, 37, 71\n// g(bool): true -> 23, 37, 71\n" + }, + "storage_array_encoding.sol": { + "content": "pragma abicoder v2;\n\n// tests encoding from storage arrays\n\ncontract C {\n uint256[2][] tmp_h;\n function h(uint256[2][] calldata s) external returns (bytes memory) {\n tmp_h = s;\n return abi.encode(tmp_h);\n }\n uint256[2][2] tmp_i;\n function i(uint256[2][2] calldata s) external returns (bytes memory) {\n tmp_i = s;\n return abi.encode(tmp_i);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324\n// gas irOptimized: 180080\n// gas legacy: 184233\n// gas legacyOptimized: 180856\n// i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224\n// gas irOptimized: 112031\n// gas legacy: 115091\n// gas legacyOptimized: 112657\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct.sol b/examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct.sol new file mode 100644 index 00000000..5c13d791 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct.sol @@ -0,0 +1,12 @@ +pragma abicoder v2; + +contract C { + struct S { C c; uint[] x; } + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { + r1 = a; + r2 = s1[0].c; + r3 = b; + } +} +// ---- +// f(uint256,(address,uint256[])[2],uint256): 7, 0x60, 8, 0x40, 0xE0, 0x0, 0x40, 2, 0x11, 0x12, 0x99, 0x40, 4, 0x31, 0x32, 0x34, 0x35 -> 7, 0x0, 8 diff --git a/examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct_standard_input.json new file mode 100644 index 00000000..656a35bb --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_mediocre2_struct/mediocre2_struct_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + }, + "struct_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external returns (uint) f; uint b; }\n function f(S memory s) public returns (uint, uint) {\n return (s.f(), s.b);\n }\n function test() public returns (uint, uint) {\n return this.f(S(this.g, 3));\n }\n function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n" + }, + "struct_validation.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { int16 a; uint8 b; bytes2 c; }\n\tfunction f(S memory s) public pure returns (uint a, uint b, uint c) {\n\t\tassembly {\n\t\t\ta := mload(s)\n\t\t\tb := mload(add(s, 0x20))\n\t\t\tc := mload(add(s, 0x40))\n\t\t}\n\t}\n}\n// ----\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\"\n// f((int16,uint8,bytes2)): 0xff010, 0xff, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"abcd\" -> FAILURE\n" + }, + "mediocre_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { C c; }\n function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n r1 = a;\n r2 = s1[0].c;\n r3 = b;\n }\n}\n// ----\n// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8\n" + }, + "validation_function_type_inside_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external x; }\n function f(S memory) public pure returns (uint r) { r = 1; }\n function g(S calldata) external pure returns (uint r) { r = 2; }\n function h(S calldata s) external pure returns (uint r) { s.x; r = 3; }\n}\n// ----\n// f((function)): \"01234567890123456789abcd\" -> 1\n// f((function)): \"01234567890123456789abcdX\" -> FAILURE\n// g((function)): \"01234567890123456789abcd\" -> 2\n// g((function)): \"01234567890123456789abcdX\" -> 2\n// h((function)): \"01234567890123456789abcd\" -> 3\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + }, + "struct_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { int a; uint b; bytes16 c; }\n function f(S memory s) public pure returns (S memory q) {\n q = s;\n }\n}\n// ----\n// f((int256,uint256,bytes16)): 0xff010, 0xff0002, \"abcd\" -> 0xff010, 0xff0002, \"abcd\"\n// f((int256,uint256,bytes16)): 0xff010, 0xff0002, 0x1111222233334444555566667777888800000000000000000000000000000000 -> 0xff010, 0xff0002, left(0x11112222333344445555666677778888)\n" + }, + "mediocre2_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { C c; uint[] x; }\n function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n r1 = a;\n r2 = s1[0].c;\n r3 = b;\n }\n}\n// ----\n// f(uint256,(address,uint256[])[2],uint256): 7, 0x60, 8, 0x40, 0xE0, 0x0, 0x40, 2, 0x11, 0x12, 0x99, 0x40, 4, 0x31, 0x32, 0x34, 0x35 -> 7, 0x0, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct.sol b/examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct.sol new file mode 100644 index 00000000..c5ab31dc --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct.sol @@ -0,0 +1,12 @@ +pragma abicoder v2; + +contract C { + struct S { C c; } + function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) { + r1 = a; + r2 = s1[0].c; + r3 = b; + } +} +// ---- +// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8 diff --git a/examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct_standard_input.json new file mode 100644 index 00000000..1918ec86 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_mediocre_struct/mediocre_struct_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + }, + "struct_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external returns (uint) f; uint b; }\n function f(S memory s) public returns (uint, uint) {\n return (s.f(), s.b);\n }\n function test() public returns (uint, uint) {\n return this.f(S(this.g, 3));\n }\n function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n" + }, + "struct_validation.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { int16 a; uint8 b; bytes2 c; }\n\tfunction f(S memory s) public pure returns (uint a, uint b, uint c) {\n\t\tassembly {\n\t\t\ta := mload(s)\n\t\t\tb := mload(add(s, 0x20))\n\t\t\tc := mload(add(s, 0x40))\n\t\t}\n\t}\n}\n// ----\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\"\n// f((int16,uint8,bytes2)): 0xff010, 0xff, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"abcd\" -> FAILURE\n" + }, + "mediocre_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { C c; }\n function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n r1 = a;\n r2 = s1[0].c;\n r3 = b;\n }\n}\n// ----\n// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function.sol b/examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function.sol new file mode 100644 index 00000000..3217a173 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + +contract C { + struct S { function () external returns (uint) f; uint b; } + function f(S memory s) public returns (uint, uint) { + return (s.f(), s.b); + } + function test() public returns (uint, uint) { + return this.f(S(this.g, 3)); + } + function g() public returns (uint) { return 7; } +} +// ---- +// test() -> 7, 3 diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function_standard_input.json new file mode 100644 index 00000000..e9d6c340 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_function/struct_function_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + }, + "struct_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external returns (uint) f; uint b; }\n function f(S memory s) public returns (uint, uint) {\n return (s.f(), s.b);\n }\n function test() public returns (uint, uint) {\n return this.f(S(this.g, 3));\n }\n function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short.sol b/examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short.sol new file mode 100644 index 00000000..ce6550d3 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; + +contract C { + struct S { int a; uint b; bytes16 c; } + function f(S memory s) public pure returns (S memory q) { + q = s; + } +} +// ---- +// f((int256,uint256,bytes16)): 0xff010, 0xff0002, "abcd" -> 0xff010, 0xff0002, "abcd" +// f((int256,uint256,bytes16)): 0xff010, 0xff0002, 0x1111222233334444555566667777888800000000000000000000000000000000 -> 0xff010, 0xff0002, left(0x11112222333344445555666677778888) diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short_standard_input.json new file mode 100644 index 00000000..00801180 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_short/struct_short_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + }, + "struct_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external returns (uint) f; uint b; }\n function f(S memory s) public returns (uint, uint) {\n return (s.f(), s.b);\n }\n function test() public returns (uint, uint) {\n return this.f(S(this.g, 3));\n }\n function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n" + }, + "struct_validation.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { int16 a; uint8 b; bytes2 c; }\n\tfunction f(S memory s) public pure returns (uint a, uint b, uint c) {\n\t\tassembly {\n\t\t\ta := mload(s)\n\t\t\tb := mload(add(s, 0x20))\n\t\t\tc := mload(add(s, 0x40))\n\t\t}\n\t}\n}\n// ----\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\"\n// f((int16,uint8,bytes2)): 0xff010, 0xff, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"abcd\" -> FAILURE\n" + }, + "mediocre_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { C c; }\n function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n r1 = a;\n r2 = s1[0].c;\n r3 = b;\n }\n}\n// ----\n// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8\n" + }, + "validation_function_type_inside_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external x; }\n function f(S memory) public pure returns (uint r) { r = 1; }\n function g(S calldata) external pure returns (uint r) { r = 2; }\n function h(S calldata s) external pure returns (uint r) { s.x; r = 3; }\n}\n// ----\n// f((function)): \"01234567890123456789abcd\" -> 1\n// f((function)): \"01234567890123456789abcdX\" -> FAILURE\n// g((function)): \"01234567890123456789abcd\" -> 2\n// g((function)): \"01234567890123456789abcdX\" -> 2\n// h((function)): \"01234567890123456789abcd\" -> 3\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + }, + "struct_short.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { int a; uint b; bytes16 c; }\n function f(S memory s) public pure returns (S memory q) {\n q = s;\n }\n}\n// ----\n// f((int256,uint256,bytes16)): 0xff010, 0xff0002, \"abcd\" -> 0xff010, 0xff0002, \"abcd\"\n// f((int256,uint256,bytes16)): 0xff010, 0xff0002, 0x1111222233334444555566667777888800000000000000000000000000000000 -> 0xff010, 0xff0002, left(0x11112222333344445555666677778888)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple.sol b/examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple.sol new file mode 100644 index 00000000..cf631b8a --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; + +contract C { + struct S { uint a; uint8 b; uint8 c; bytes2 d; } + function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) { + a = s.a; + b = s.b; + c = s.c; + d = uint16(s.d); + } +} +// ---- +// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, "ab" -> 1, 2, 3, 0x6162 diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple_standard_input.json new file mode 100644 index 00000000..82d1eb5c --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_simple/struct_simple_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation.sol b/examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation.sol new file mode 100644 index 00000000..57e218f7 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; + +contract C { + struct S { int16 a; uint8 b; bytes2 c; } + function f(S memory s) public pure returns (uint a, uint b, uint c) { + assembly { + a := mload(s) + b := mload(add(s, 0x20)) + c := mload(add(s, 0x40)) + } + } +} +// ---- +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "ab" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "ab" +// f((int16,uint8,bytes2)): 0xff010, 0xff, "ab" -> FAILURE +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, "ab" -> FAILURE +// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, "abcd" -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation_standard_input.json new file mode 100644 index 00000000..e207ff68 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_struct_validation/struct_validation_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + }, + "struct_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external returns (uint) f; uint b; }\n function f(S memory s) public returns (uint, uint) {\n return (s.f(), s.b);\n }\n function test() public returns (uint, uint) {\n return this.f(S(this.g, 3));\n }\n function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n" + }, + "struct_validation.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { int16 a; uint8 b; bytes2 c; }\n\tfunction f(S memory s) public pure returns (uint a, uint b, uint c) {\n\t\tassembly {\n\t\t\ta := mload(s)\n\t\t\tb := mload(add(s, 0x20))\n\t\t\tc := mload(add(s, 0x40))\n\t\t}\n\t}\n}\n// ----\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\"\n// f((int16,uint8,bytes2)): 0xff010, 0xff, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"abcd\" -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct.sol b/examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct.sol new file mode 100644 index 00000000..8a22b037 --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + +contract C { + struct S { function () external x; } + function f(S memory) public pure returns (uint r) { r = 1; } + function g(S calldata) external pure returns (uint r) { r = 2; } + function h(S calldata s) external pure returns (uint r) { s.x; r = 3; } +} +// ---- +// f((function)): "01234567890123456789abcd" -> 1 +// f((function)): "01234567890123456789abcdX" -> FAILURE +// g((function)): "01234567890123456789abcd" -> 2 +// g((function)): "01234567890123456789abcdX" -> 2 +// h((function)): "01234567890123456789abcd" -> 3 +// h((function)): "01234567890123456789abcdX" -> FAILURE diff --git a/examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct_standard_input.json b/examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct_standard_input.json new file mode 100644 index 00000000..96db846d --- /dev/null +++ b/examples/test/semanticTests/abiEncoderV2_struct_validation_function_type_inside_struct/validation_function_type_inside_struct_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "struct_simple.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { uint a; uint8 b; uint8 c; bytes2 d; }\n function f(S memory s) public pure returns (uint a, uint b, uint c, uint d) {\n a = s.a;\n b = s.b;\n c = s.c;\n d = uint16(s.d);\n }\n}\n// ----\n// f((uint256,uint8,uint8,bytes2)): 1, 2, 3, \"ab\" -> 1, 2, 3, 0x6162\n" + }, + "struct_function.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external returns (uint) f; uint b; }\n function f(S memory s) public returns (uint, uint) {\n return (s.f(), s.b);\n }\n function test() public returns (uint, uint) {\n return this.f(S(this.g, 3));\n }\n function g() public returns (uint) { return 7; }\n}\n// ----\n// test() -> 7, 3\n" + }, + "struct_validation.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { int16 a; uint8 b; bytes2 c; }\n\tfunction f(S memory s) public pure returns (uint a, uint b, uint c) {\n\t\tassembly {\n\t\t\ta := mload(s)\n\t\t\tb := mload(add(s, 0x20))\n\t\t\tc := mload(add(s, 0x40))\n\t\t}\n\t}\n}\n// ----\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\" -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"ab\"\n// f((int16,uint8,bytes2)): 0xff010, 0xff, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff0002, \"ab\" -> FAILURE\n// f((int16,uint8,bytes2)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01, 0xff, \"abcd\" -> FAILURE\n" + }, + "mediocre_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { C c; }\n function f(uint a, S[2] memory s1, uint b) public returns (uint r1, C r2, uint r3) {\n r1 = a;\n r2 = s1[0].c;\n r3 = b;\n }\n}\n// ----\n// f(uint256,(address)[2],uint256): 7, 0, 0, 8 -> 7, 0, 8\n" + }, + "validation_function_type_inside_struct.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S { function () external x; }\n function f(S memory) public pure returns (uint r) { r = 1; }\n function g(S calldata) external pure returns (uint r) { r = 2; }\n function h(S calldata s) external pure returns (uint r) { s.x; r = 3; }\n}\n// ----\n// f((function)): \"01234567890123456789abcd\" -> 1\n// f((function)): \"01234567890123456789abcdX\" -> FAILURE\n// g((function)): \"01234567890123456789abcd\" -> 2\n// g((function)): \"01234567890123456789abcdX\" -> 2\n// h((function)): \"01234567890123456789abcd\" -> 3\n// h((function)): \"01234567890123456789abcdX\" -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata.sol b/examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata.sol new file mode 100644 index 00000000..6b6e55e0 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata.sol @@ -0,0 +1,11 @@ +contract C { + function f(bytes calldata data) + external + pure + returns (uint256, bytes memory r) + { + return abi.decode(data, (uint256, bytes)); + } +} +// ---- +// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" diff --git a/examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata_standard_input.json new file mode 100644 index 00000000..00e5f57e --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_decode_calldata/abi_decode_calldata_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple.sol b/examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple.sol new file mode 100644 index 00000000..9ae6602f --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes memory data) public pure returns (uint256, bytes memory) { + return abi.decode(data, (uint256, bytes)); + } +} +// ---- +// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" diff --git a/examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple_standard_input.json new file mode 100644 index 00000000..1ca2c8bd --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_decode_simple/abi_decode_simple_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + }, + "abi_decode_simple.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256, bytes memory) {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage.sol b/examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage.sol new file mode 100644 index 00000000..54ce693d --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage.sol @@ -0,0 +1,13 @@ +contract C { + bytes data; + + function f(bytes memory _data) public returns (uint256, bytes memory) { + data = _data; + return abi.decode(data, (uint256, bytes)); + } +} +// ---- +// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" +// gas irOptimized: 135499 +// gas legacy: 137095 +// gas legacyOptimized: 135823 diff --git a/examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage_standard_input.json new file mode 100644 index 00000000..581f1f1a --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_decode_simple_storage/abi_decode_simple_storage_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + }, + "abi_decode_simple.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256, bytes memory) {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_call_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract D {\n\tfunction something() external pure {}\n}\n\ncontract C {\n\tfunction something() external pure {}\n\tfunction test() external returns (bytes4) {\n\t\tfunction() external[2] memory x;\n\t\tx[0] = this.something;\n\t\tx[1] = (new D()).something;\n\t\tfunction() external f = x[1];\n\t\tbytes memory a = abi.encodeCall(x[0], ());\n\t\tbytes memory b = abi.encodeCall(x[1], ());\n\t\tbytes memory c = abi.encodeCall(f, ());\n\t\tassert(a.length == 4 && b.length == 4 && c.length == 4);\n\t\tassert(bytes4(a) == bytes4(b));\n\t\tassert(bytes4(a) == bytes4(c));\n\t\tassert(bytes4(a) == f.selector);\n\t\treturn bytes4(a);\n\t}\n}\n// ----\n// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000\n" + }, + "abi_decode_simple_storage.sol": { + "content": "contract C {\n bytes data;\n\n function f(bytes memory _data) public returns (uint256, bytes memory) {\n data = _data;\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// gas irOptimized: 135499\n// gas legacy: 137095\n// gas legacyOptimized: 135823\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call.sol new file mode 100644 index 00000000..1edede78 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call.sol @@ -0,0 +1,48 @@ +pragma abicoder v2; +contract C { + type UnsignedNumber is uint256; + enum Enum { First, Second, Third } + + struct Struct { + UnsignedNumber[] dynamicArray; + uint256 justAnInt; + string name; + bytes someBytes; + Enum theEnum; + } + + function callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure { + assert(_data.dynamicArray.length == 3); + assert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0); + assert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1); + assert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2); + assert(_data.justAnInt == 6); + assert(keccak256(bytes(_data.name)) == keccak256("StructName")); + assert(keccak256(_data.someBytes) == keccak256(bytes("1234"))); + assert(_data.theEnum == Enum.Second); + assert(_intVal == 5); + assert(keccak256(bytes(_nameVal)) == keccak256("TestName")); + } + + function callExternal() public returns (bool) { + Struct memory structToSend; + structToSend.dynamicArray = new UnsignedNumber[](3); + structToSend.dynamicArray[0] = UnsignedNumber.wrap(0); + structToSend.dynamicArray[1] = UnsignedNumber.wrap(1); + structToSend.dynamicArray[2] = UnsignedNumber.wrap(2); + structToSend.justAnInt = 6; + structToSend.name = "StructName"; + structToSend.someBytes = bytes("1234"); + structToSend.theEnum = Enum.Second; + + (bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, ( + structToSend, + 5, + "TestName" + ))); + + return success; + } +} +// ---- +// callExternal() -> true diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call_standard_input.json new file mode 100644 index 00000000..2cf70966 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call/abi_encode_call_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration.sol new file mode 100644 index 00000000..752298fb --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration.sol @@ -0,0 +1,52 @@ +pragma abicoder v2; + +contract X { + // no "returns" on purpose + function a(uint) public pure {} + function b(uint) external pure {} +} + +contract Base { + function a(uint x) external pure returns (uint) { return x + 1; } +} + +contract C is Base { + function test() public view returns (uint r) { + bool success; + bytes memory result; + (success, result) = address(this).staticcall(abi.encodeCall(X.a, 1)); + require(success && result.length == 32); + r += abi.decode(result, (uint)); + require(r == 2); + + (success, result) = address(this).staticcall(abi.encodeCall(X.b, 10)); + require(success && result.length == 32); + r += abi.decode(result, (uint)); + require(r == 13); + + (success, result) = address(this).staticcall(abi.encodeCall(Base.a, 100)); + require(success && result.length == 32); + r += abi.decode(result, (uint)); + require(r == 114); + + (success, result) = address(this).staticcall(abi.encodeCall(this.a, 1000)); + require(success && result.length == 32); + r += abi.decode(result, (uint)); + require(r == 1115); + + (success, result) = address(this).staticcall(abi.encodeCall(C.b, 10000)); + require(success && result.length == 32); + r += abi.decode(result, (uint)); + require(r == 11116); + + return r; + } + function b(uint x) external view returns (uint) { + return this.a(x); + } + +} +// ==== +// EVMVersion: >=byzantium +// ---- +// test() -> 11116 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration_standard_input.json new file mode 100644 index 00000000..6fdc6b84 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_declaration/abi_encode_call_declaration_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + }, + "abi_decode_simple.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256, bytes memory) {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_call_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract D {\n\tfunction something() external pure {}\n}\n\ncontract C {\n\tfunction something() external pure {}\n\tfunction test() external returns (bytes4) {\n\t\tfunction() external[2] memory x;\n\t\tx[0] = this.something;\n\t\tx[1] = (new D()).something;\n\t\tfunction() external f = x[1];\n\t\tbytes memory a = abi.encodeCall(x[0], ());\n\t\tbytes memory b = abi.encodeCall(x[1], ());\n\t\tbytes memory c = abi.encodeCall(f, ());\n\t\tassert(a.length == 4 && b.length == 4 && c.length == 4);\n\t\tassert(bytes4(a) == bytes4(b));\n\t\tassert(bytes4(a) == bytes4(c));\n\t\tassert(bytes4(a) == f.selector);\n\t\treturn bytes4(a);\n\t}\n}\n// ----\n// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000\n" + }, + "abi_decode_simple_storage.sol": { + "content": "contract C {\n bytes data;\n\n function f(bytes memory _data) public returns (uint256, bytes memory) {\n data = _data;\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// gas irOptimized: 135499\n// gas legacy: 137095\n// gas legacyOptimized: 135823\n" + }, + "contract_array.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_declaration.sol": { + "content": "pragma abicoder v2;\n\ncontract X {\n // no \"returns\" on purpose\n function a(uint) public pure {}\n function b(uint) external pure {}\n}\n\ncontract Base {\n function a(uint x) external pure returns (uint) { return x + 1; }\n}\n\ncontract C is Base {\n\tfunction test() public view returns (uint r) {\n bool success;\n bytes memory result;\n (success, result) = address(this).staticcall(abi.encodeCall(X.a, 1));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 2);\n\n (success, result) = address(this).staticcall(abi.encodeCall(X.b, 10));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 13);\n\n (success, result) = address(this).staticcall(abi.encodeCall(Base.a, 100));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 114);\n\n (success, result) = address(this).staticcall(abi.encodeCall(this.a, 1000));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 1115);\n\n (success, result) = address(this).staticcall(abi.encodeCall(C.b, 10000));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 11116);\n\n return r;\n\t}\n function b(uint x) external view returns (uint) {\n return this.a(x);\n }\n\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> 11116\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent.sol new file mode 100644 index 00000000..c54d6083 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent.sol @@ -0,0 +1,61 @@ +pragma abicoder v2; + +contract C { + bool sideEffectRan = false; + + function(uint256, string memory) external fPointer; + function fExternal(uint256 p, string memory t) external {} + string xstor; + function getExternalFunctionPointer() public returns (function(uint256, string memory) external) { + sideEffectRan = true; + return this.fExternal; + } + + function fSignatureFromLiteral() public pure returns (bytes memory) { + return abi.encodeWithSignature("fExternal(uint256,string)", 1, "123"); + } + function fSignatureFromLiteralCall() public view returns (bytes memory) { + return abi.encodeCall(this.fExternal, (1, "123")); + } + function fSignatureFromMemory() public pure returns (bytes memory) { + string memory x = "fExternal(uint256,string)"; + return abi.encodeWithSignature(x, 1, "123"); + } + function fSignatureFromMemoryCall() public view returns (bytes memory) { + return abi.encodeCall(this.fExternal, (1,"123")); + } + function fSignatureFromMemorys() public returns (bytes memory) { + xstor = "fExternal(uint256,string)"; + return abi.encodeWithSignature(xstor, 1, "123"); + } + function fPointerCall() public returns(bytes memory) { + fPointer = this.fExternal; + return abi.encodeCall(fPointer, (1, "123")); + } + function fLocalPointerCall() public returns(bytes memory) { + function(uint256, string memory) external localFunctionPointer = this.fExternal; + return abi.encodeCall(localFunctionPointer, (1, "123")); + } + function fReturnedFunctionPointer() public returns (bytes memory) { + return abi.encodeCall(getExternalFunctionPointer(), (1, "123")); + } + + function assertConsistentSelectors() public { + assert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall())); + assert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall())); + assert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys())); + assert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral())); + assert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral())); + assert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral())); + } +} +// ---- +// assertConsistentSelectors() -> +// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 +// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent_standard_input.json new file mode 100644 index 00000000..2c7f6aca --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_is_consistent/abi_encode_call_is_consistent_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory.sol new file mode 100644 index 00000000..5f67174c --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract D { + function something() external pure {} +} + +contract C { + function something() external pure {} + function test() external returns (bytes4) { + function() external[2] memory x; + x[0] = this.something; + x[1] = (new D()).something; + function() external f = x[1]; + bytes memory a = abi.encodeCall(x[0], ()); + bytes memory b = abi.encodeCall(x[1], ()); + bytes memory c = abi.encodeCall(f, ()); + assert(a.length == 4 && b.length == 4 && c.length == 4); + assert(bytes4(a) == bytes4(b)); + assert(bytes4(a) == bytes4(c)); + assert(bytes4(a) == f.selector); + return bytes4(a); + } +} +// ---- +// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory_standard_input.json new file mode 100644 index 00000000..1218effd --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_memory/abi_encode_call_memory_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + }, + "abi_decode_simple.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256, bytes memory) {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_call_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract D {\n\tfunction something() external pure {}\n}\n\ncontract C {\n\tfunction something() external pure {}\n\tfunction test() external returns (bytes4) {\n\t\tfunction() external[2] memory x;\n\t\tx[0] = this.something;\n\t\tx[1] = (new D()).something;\n\t\tfunction() external f = x[1];\n\t\tbytes memory a = abi.encodeCall(x[0], ());\n\t\tbytes memory b = abi.encodeCall(x[1], ());\n\t\tbytes memory c = abi.encodeCall(f, ());\n\t\tassert(a.length == 4 && b.length == 4 && c.length == 4);\n\t\tassert(bytes4(a) == bytes4(b));\n\t\tassert(bytes4(a) == bytes4(c));\n\t\tassert(bytes4(a) == f.selector);\n\t\treturn bytes4(a);\n\t}\n}\n// ----\n// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args.sol new file mode 100644 index 00000000..0ce29f40 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args.sol @@ -0,0 +1,46 @@ +pragma abicoder v2; + +contract C { + bool sideEffectRan = false; + + function fNoArgs() external {} + function fArray(uint[] memory x) external {} + function fUint(uint x, uint y) external returns (uint a, uint b) {} + + function fSignatureFromLiteralNoArgs() public pure returns (bytes memory) { + return abi.encodeWithSignature("fNoArgs()"); + } + function fPointerNoArgs() public view returns (bytes memory) { + return abi.encodeCall(this.fNoArgs, ()); + } + + function fSignatureFromLiteralArray() public pure returns (bytes memory) { + uint[] memory x; + return abi.encodeWithSignature("fArray(uint256[])", x); + } + function fPointerArray() public view returns (bytes memory) { + uint[] memory x; + return abi.encodeCall(this.fArray, x); + } + + function fSignatureFromLiteralUint() public pure returns (bytes memory) { + return abi.encodeWithSignature("fUint(uint256,uint256)", 12, 13); + } + function fPointerUint() public view returns (bytes memory) { + return abi.encodeCall(this.fUint, (12,13)); + } + + function assertConsistentSelectors() public view { + assert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs())); + assert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray())); + assert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint())); + } +} +// ---- +// assertConsistentSelectors() -> +// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832 +// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832 +// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0 +// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808 +// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args_standard_input.json new file mode 100644 index 00000000..3086e995 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_special_args/abi_encode_call_special_args_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes.sol new file mode 100644 index 00000000..ec1ea14b --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes.sol @@ -0,0 +1,20 @@ +contract C { + function removeSignature(bytes calldata x) external pure returns (bytes memory) { + return x[4:]; + } + function g(bytes2, bytes2, bytes2) public {} + function h(uint16, uint16) public {} + function f() public returns (bytes memory) { + uint16 x = 0x1234; + return this.removeSignature(abi.encodeCall(this.g, (0x1234, "ab", bytes2(x)))); + } + function f2() public returns (bytes memory) { + bytes2 x = 0x1234; + return this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x)))); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000 +// f2() -> 0x20, 0x40, 0x1234, 0x1234 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes_standard_input.json new file mode 100644 index 00000000..0c2de5d7 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_call_uint_bytes/abi_encode_call_uint_bytes_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1.sol new file mode 100644 index 00000000..9f7216e6 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1.sol @@ -0,0 +1,13 @@ +pragma abicoder v1; +// Tests that this will not end up using a "bytes0" type +// (which would assert) +contract C { + function f() public pure returns (bytes memory, bytes memory) { + return (abi.encode(""), abi.encodePacked("")); + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1_standard_input.json new file mode 100644 index 00000000..7f7e49bc --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_empty_string_v1/abi_encode_empty_string_v1_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + }, + "abi_decode_simple.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256, bytes memory) {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_call_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract D {\n\tfunction something() external pure {}\n}\n\ncontract C {\n\tfunction something() external pure {}\n\tfunction test() external returns (bytes4) {\n\t\tfunction() external[2] memory x;\n\t\tx[0] = this.something;\n\t\tx[1] = (new D()).something;\n\t\tfunction() external f = x[1];\n\t\tbytes memory a = abi.encodeCall(x[0], ());\n\t\tbytes memory b = abi.encodeCall(x[1], ());\n\t\tbytes memory c = abi.encodeCall(f, ());\n\t\tassert(a.length == 4 && b.length == 4 && c.length == 4);\n\t\tassert(bytes4(a) == bytes4(b));\n\t\tassert(bytes4(a) == bytes4(c));\n\t\tassert(bytes4(a) == f.selector);\n\t\treturn bytes4(a);\n\t}\n}\n// ----\n// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000\n" + }, + "abi_decode_simple_storage.sol": { + "content": "contract C {\n bytes data;\n\n function f(bytes memory _data) public returns (uint256, bytes memory) {\n data = _data;\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// gas irOptimized: 135499\n// gas legacy: 137095\n// gas legacyOptimized: 135823\n" + }, + "contract_array.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_declaration.sol": { + "content": "pragma abicoder v2;\n\ncontract X {\n // no \"returns\" on purpose\n function a(uint) public pure {}\n function b(uint) external pure {}\n}\n\ncontract Base {\n function a(uint x) external pure returns (uint) { return x + 1; }\n}\n\ncontract C is Base {\n\tfunction test() public view returns (uint r) {\n bool success;\n bytes memory result;\n (success, result) = address(this).staticcall(abi.encodeCall(X.a, 1));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 2);\n\n (success, result) = address(this).staticcall(abi.encodeCall(X.b, 10));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 13);\n\n (success, result) = address(this).staticcall(abi.encodeCall(Base.a, 100));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 114);\n\n (success, result) = address(this).staticcall(abi.encodeCall(this.a, 1000));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 1115);\n\n (success, result) = address(this).staticcall(abi.encodeCall(C.b, 10000));\n require(success && result.length == 32);\n r += abi.decode(result, (uint));\n require(r == 11116);\n\n return r;\n\t}\n function b(uint x) external view returns (uint) {\n return this.a(x);\n }\n\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> 11116\n" + }, + "abi_encode_empty_string_v1.sol": { + "content": "pragma abicoder v1;\n// Tests that this will not end up using a \"bytes0\" type\n// (which would assert)\ncontract C {\n function f() public pure returns (bytes memory, bytes memory) {\n return (abi.encode(\"\"), abi.encodePacked(\"\"));\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f() -> 0x40, 0xa0, 0x40, 0x20, 0x0, 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector.sol new file mode 100644 index 00000000..f72de437 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector.sol @@ -0,0 +1,22 @@ +pragma abicoder v1; +contract C { + function f0() public pure returns (bytes memory) { + return abi.encodeWithSelector(0x12345678); + } + function f1() public pure returns (bytes memory) { + return abi.encodeWithSelector(0x12345678, "abc"); + } + function f2() public pure returns (bytes memory) { + bytes4 x = 0x12345678; + return abi.encodeWithSelector(x, "abc"); + } + function f3() public pure returns (bytes memory) { + bytes4 x = 0x12345678; + return abi.encodeWithSelector(x, type(uint).max); + } +} +// ---- +// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536 +// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector_standard_input.json new file mode 100644 index 00000000..1d70d5a9 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selector/abi_encode_with_selector_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2.sol new file mode 100644 index 00000000..b23e2dd2 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2.sol @@ -0,0 +1,32 @@ +pragma abicoder v2; +contract C { + function f0() public pure returns (bytes memory) { + return abi.encodeWithSelector(0x12345678); + } + function f1() public pure returns (bytes memory) { + return abi.encodeWithSelector(0x12345678, "abc"); + } + function f2() public pure returns (bytes memory) { + bytes4 x = 0x12345678; + return abi.encodeWithSelector(x, "abc"); + } + function f3() public pure returns (bytes memory) { + bytes4 x = 0x12345678; + return abi.encodeWithSelector(x, type(uint).max); + } + struct S { uint a; string b; uint16 c; } + function f4() public pure returns (bytes memory) { + bytes4 x = 0x12345678; + S memory s; + s.a = 0x1234567; + s.b = "Lorem ipsum dolor sit ethereum........"; + s.c = 0x1234; + return abi.encodeWithSelector(x, type(uint).max, s, uint(3)); + } +} +// ---- +// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536 +// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216 +// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2_standard_input.json new file mode 100644 index 00000000..da6ffb8b --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_selectorv2/abi_encode_with_selectorv2_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature.sol new file mode 100644 index 00000000..61a8d0b4 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature.sol @@ -0,0 +1,32 @@ +pragma abicoder v1; +contract C { + function f0() public pure returns (bytes memory) { + return abi.encodeWithSignature("f(uint256)"); + } + function f1() public pure returns (bytes memory) { + string memory x = "f(uint256)"; + return abi.encodeWithSignature(x, "abc"); + } + string xstor; + function f1s() public returns (bytes memory) { + xstor = "f(uint256)"; + return abi.encodeWithSignature(xstor, "abc"); + } + function f2() public pure returns (bytes memory r, uint[] memory ar) { + string memory x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + uint[] memory y = new uint[](4); + y[0] = type(uint).max; + y[1] = type(uint).max - 1; + y[2] = type(uint).max - 2; + y[3] = type(uint).max - 3; + r = abi.encodeWithSignature(x, y); + // The hash uses temporary memory. This allocation re-uses the memory + // and should initialize it properly. + ar = new uint[](2); + } +} +// ---- +// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616 +// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature_standard_input.json new file mode 100644 index 00000000..dd4050dd --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signature/abi_encode_with_signature_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2.sol b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2.sol new file mode 100644 index 00000000..40205308 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; +contract C { + function f0() public pure returns (bytes memory) { + return abi.encodeWithSignature("f(uint256)"); + } + function f1() public pure returns (bytes memory) { + string memory x = "f(uint256)"; + return abi.encodeWithSignature(x, "abc"); + } + string xstor; + function f1s() public returns (bytes memory) { + xstor = "f(uint256)"; + return abi.encodeWithSignature(xstor, "abc"); + } + function f2() public pure returns (bytes memory r, uint[] memory ar) { + string memory x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + uint[] memory y = new uint[](4); + y[0] = type(uint).max; + y[1] = type(uint).max - 1; + y[2] = type(uint).max - 2; + y[3] = type(uint).max - 3; + r = abi.encodeWithSignature(x, y); + // The hash uses temporary memory. This allocation re-uses the memory + // and should initialize it properly. + ar = new uint[](2); + } + struct S { uint a; string b; uint16 c; } + function f4() public pure returns (bytes memory) { + S memory s; + s.a = 0x1234567; + s.b = "Lorem ipsum dolor sit ethereum........"; + s.c = 0x1234; + return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3)); + } +} +// ---- +// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616 +// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0 +// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0 +// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0 diff --git a/examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2_standard_input.json b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2_standard_input.json new file mode 100644 index 00000000..62b66854 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_abi_encode_with_signaturev2/abi_encode_with_signaturev2_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_contract_array/contract_array.sol b/examples/test/semanticTests/abiencodedecode_contract_array/contract_array.sol new file mode 100644 index 00000000..7187ccf5 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_contract_array/contract_array.sol @@ -0,0 +1,15 @@ +contract C { + function f(bytes calldata x) public returns (C[] memory) { + return abi.decode(x, (C[])); + } + function g() public returns (bytes memory) { + C[] memory c = new C[](3); + c[0] = C(address(0x42)); + c[1] = C(address(0x21)); + c[2] = C(address(0x23)); + return abi.encode(c); + } +} +// ---- +// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03 +// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23 diff --git a/examples/test/semanticTests/abiencodedecode_contract_array/contract_array_standard_input.json b/examples/test/semanticTests/abiencodedecode_contract_array/contract_array_standard_input.json new file mode 100644 index 00000000..0e42437f --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_contract_array/contract_array_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "abi_encode_call_special_args.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction fNoArgs() external {}\n\tfunction fArray(uint[] memory x) external {}\n\tfunction fUint(uint x, uint y) external returns (uint a, uint b) {}\n\n\tfunction fSignatureFromLiteralNoArgs() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fNoArgs()\");\n\t}\n\tfunction fPointerNoArgs() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fNoArgs, ());\n\t}\n\n\tfunction fSignatureFromLiteralArray() public pure returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeWithSignature(\"fArray(uint256[])\", x);\n\t}\n\tfunction fPointerArray() public view returns (bytes memory) {\n\t\tuint[] memory x;\n\t\treturn abi.encodeCall(this.fArray, x);\n\t}\n\n\tfunction fSignatureFromLiteralUint() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fUint(uint256,uint256)\", 12, 13);\n\t}\n\tfunction fPointerUint() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fUint, (12,13));\n\t}\n\n\tfunction assertConsistentSelectors() public view {\n\t\tassert(keccak256(fSignatureFromLiteralNoArgs()) == keccak256(fPointerNoArgs()));\n\t\tassert(keccak256(fSignatureFromLiteralArray()) == keccak256(fPointerArray()));\n\t\tassert(keccak256(fSignatureFromLiteralUint()) == keccak256(fPointerUint()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteralNoArgs() -> 0x20, 0x04, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fPointerNoArgs() -> 0x20, 4, 12200448252684243758085936796735499259670113115893304444050964496075123064832\n// fSignatureFromLiteralArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerArray() -> 0x20, 0x44, 4612216551196396486909126966576324289294165774260092952932219511233230929920, 862718293348820473429344482784628181556388621521298319395315527974912, 0\n// fPointerUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n// fSignatureFromLiteralUint() -> 0x20, 0x44, 30372892641494467502622535050667754357470287521126424526399600764424271429632, 323519360005807677536004181044235568083645733070486869773243322990592, 350479306672958317330671196131255198757282877493027442254346933239808\n" + }, + "abi_decode_calldata.sol": { + "content": "contract C {\n function f(bytes calldata data)\n external\n pure\n returns (uint256, bytes memory r)\n {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_with_selector.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "abi_encode_with_signature.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"f(uint256)\");\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\tstring memory x = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(x, \"abc\");\n\t}\n\tstring xstor;\n\tfunction f1s() public returns (bytes memory) {\n\t\txstor = \"f(uint256)\";\n\t\treturn abi.encodeWithSignature(xstor, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory r, uint[] memory ar) {\n\t\tstring memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n\t\tuint[] memory y = new uint[](4);\n\t\ty[0] = type(uint).max;\n\t\ty[1] = type(uint).max - 1;\n\t\ty[2] = type(uint).max - 2;\n\t\ty[3] = type(uint).max - 3;\n\t\tr = abi.encodeWithSignature(x, y);\n\t\t// The hash uses temporary memory. This allocation re-uses the memory\n\t\t// and should initialize it properly.\n\t\tar = new uint[](2);\n\t}\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n" + }, + "abi_encode_with_selectorv2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f0() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678);\n\t}\n\tfunction f1() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSelector(0x12345678, \"abc\");\n\t}\n\tfunction f2() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, \"abc\");\n\t}\n\tfunction f3() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\treturn abi.encodeWithSelector(x, type(uint).max);\n\t}\n\tstruct S { uint a; string b; uint16 c; }\n\tfunction f4() public pure returns (bytes memory) {\n\t\tbytes4 x = 0x12345678;\n\t\tS memory s;\n\t\ts.a = 0x1234567;\n\t\ts.b = \"Lorem ipsum dolor sit ethereum........\";\n\t\ts.c = 0x1234;\n\t\treturn abi.encodeWithSelector(x, type(uint).max, s, uint(3));\n\t}\n}\n// ----\n// f0() -> 0x20, 4, 8234104107246695022420661102507966550300666591269321702959126607540084801536\n// f1() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x20, 0x64, 8234104107246695022420661102507966550300666591269321702959126607540084801536, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f3() -> 0x20, 0x24, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216\n// f4() -> 0x20, 292, 0x12345678ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "abi_encode_call.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\ttype UnsignedNumber is uint256;\n\tenum Enum { First, Second, Third }\n\n\tstruct Struct {\n\t\tUnsignedNumber[] dynamicArray;\n\t\tuint256 justAnInt;\n\t\tstring name;\n\t\tbytes someBytes;\n\t\tEnum theEnum;\n\t}\n\n\tfunction callMeMaybe(Struct calldata _data, int256 _intVal, string memory _nameVal) external pure {\n\t\tassert(_data.dynamicArray.length == 3);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[0]) == 0);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[1]) == 1);\n\t\tassert(UnsignedNumber.unwrap(_data.dynamicArray[2]) == 2);\n\t\tassert(_data.justAnInt == 6);\n\t\tassert(keccak256(bytes(_data.name)) == keccak256(\"StructName\"));\n\t\tassert(keccak256(_data.someBytes) == keccak256(bytes(\"1234\")));\n\t\tassert(_data.theEnum == Enum.Second);\n\t\tassert(_intVal == 5);\n\t\tassert(keccak256(bytes(_nameVal)) == keccak256(\"TestName\"));\n\t}\n\n\tfunction callExternal() public returns (bool) {\n\t\tStruct memory structToSend;\n\t\tstructToSend.dynamicArray = new UnsignedNumber[](3);\n\t\tstructToSend.dynamicArray[0] = UnsignedNumber.wrap(0);\n\t\tstructToSend.dynamicArray[1] = UnsignedNumber.wrap(1);\n\t\tstructToSend.dynamicArray[2] = UnsignedNumber.wrap(2);\n\t\tstructToSend.justAnInt = 6;\n\t\tstructToSend.name = \"StructName\";\n\t\tstructToSend.someBytes = bytes(\"1234\");\n\t\tstructToSend.theEnum = Enum.Second;\n\n\t\t(bool success,) = address(this).call(abi.encodeCall(this.callMeMaybe, (\n\t\t\tstructToSend,\n\t\t\t5,\n\t\t\t\"TestName\"\n\t\t)));\n\n\t\treturn success;\n\t}\n}\n// ----\n// callExternal() -> true\n" + }, + "abi_encode_call_is_consistent.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tbool sideEffectRan = false;\n\n\tfunction(uint256, string memory) external fPointer;\n\tfunction fExternal(uint256 p, string memory t) external {}\n\tstring xstor;\n\tfunction getExternalFunctionPointer() public returns (function(uint256, string memory) external) {\n\t\tsideEffectRan = true;\n\t\treturn this.fExternal;\n\t}\n\n\tfunction fSignatureFromLiteral() public pure returns (bytes memory) {\n\t\treturn abi.encodeWithSignature(\"fExternal(uint256,string)\", 1, \"123\");\n\t}\n\tfunction fSignatureFromLiteralCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1, \"123\"));\n\t}\n\tfunction fSignatureFromMemory() public pure returns (bytes memory) {\n\t\tstring memory x = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(x, 1, \"123\");\n\t}\n\tfunction fSignatureFromMemoryCall() public view returns (bytes memory) {\n\t\treturn abi.encodeCall(this.fExternal, (1,\"123\"));\n\t}\n\tfunction fSignatureFromMemorys() public returns (bytes memory) {\n\t\txstor = \"fExternal(uint256,string)\";\n\t\treturn abi.encodeWithSignature(xstor, 1, \"123\");\n\t}\n\tfunction fPointerCall() public returns(bytes memory) {\n\t\tfPointer = this.fExternal;\n\t\treturn abi.encodeCall(fPointer, (1, \"123\"));\n\t}\n\tfunction fLocalPointerCall() public returns(bytes memory) {\n\t\tfunction(uint256, string memory) external localFunctionPointer = this.fExternal;\n\t\treturn abi.encodeCall(localFunctionPointer, (1, \"123\"));\n\t}\n\tfunction fReturnedFunctionPointer() public returns (bytes memory) {\n\t\treturn abi.encodeCall(getExternalFunctionPointer(), (1, \"123\"));\n\t}\n\n\tfunction assertConsistentSelectors() public {\n\t\tassert(keccak256(fSignatureFromLiteral()) == keccak256(fSignatureFromLiteralCall()));\n\t\tassert(keccak256(fSignatureFromMemory()) == keccak256(fSignatureFromMemoryCall()));\n\t\tassert(keccak256(fSignatureFromMemoryCall()) == keccak256(fSignatureFromMemorys()));\n\t\tassert(keccak256(fPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fLocalPointerCall()) == keccak256(fSignatureFromLiteral()));\n\t\tassert(keccak256(fReturnedFunctionPointer()) == keccak256(fSignatureFromLiteral()));\n\t}\n}\n// ----\n// assertConsistentSelectors() ->\n// fSignatureFromLiteral() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromLiteralCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemory() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemoryCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fSignatureFromMemorys() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fLocalPointerCall() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n// fReturnedFunctionPointer() -> 0x20, 0x84, 23450202028776381066253055403048136312616272755117076566855971503345107992576, 26959946667150639794667015087019630673637144422540572481103610249216, 1725436586697640946858688965569256363112777243042596638790631055949824, 86060793054017993816230018372407419485142305772921726565498526629888, 0\n" + }, + "abi_decode_simple.sol": { + "content": "contract C {\n function f(bytes memory data) public pure returns (uint256, bytes memory) {\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n" + }, + "abi_encode_call_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract D {\n\tfunction something() external pure {}\n}\n\ncontract C {\n\tfunction something() external pure {}\n\tfunction test() external returns (bytes4) {\n\t\tfunction() external[2] memory x;\n\t\tx[0] = this.something;\n\t\tx[1] = (new D()).something;\n\t\tfunction() external f = x[1];\n\t\tbytes memory a = abi.encodeCall(x[0], ());\n\t\tbytes memory b = abi.encodeCall(x[1], ());\n\t\tbytes memory c = abi.encodeCall(f, ());\n\t\tassert(a.length == 4 && b.length == 4 && c.length == 4);\n\t\tassert(bytes4(a) == bytes4(b));\n\t\tassert(bytes4(a) == bytes4(c));\n\t\tassert(bytes4(a) == f.selector);\n\t\treturn bytes4(a);\n\t}\n}\n// ----\n// test() -> 0xa7a0d53700000000000000000000000000000000000000000000000000000000\n" + }, + "abi_decode_simple_storage.sol": { + "content": "contract C {\n bytes data;\n\n function f(bytes memory _data) public returns (uint256, bytes memory) {\n data = _data;\n return abi.decode(data, (uint256, bytes));\n }\n}\n// ----\n// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// gas irOptimized: 135499\n// gas legacy: 137095\n// gas legacyOptimized: 135823\n" + }, + "contract_array.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2.sol b/examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2.sol new file mode 100644 index 00000000..0e56ecf5 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; +contract C { + function f(bytes calldata x) public returns (C[] memory) { + return abi.decode(x, (C[])); + } + function g() public returns (bytes memory) { + C[] memory c = new C[](3); + c[0] = C(address(0x42)); + c[1] = C(address(0x21)); + c[2] = C(address(0x23)); + return abi.encode(c); + } +} +// ---- +// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03 +// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 +// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE +// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23 diff --git a/examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2_standard_input.json b/examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2_standard_input.json new file mode 100644 index 00000000..db468b05 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_contract_array_v2/contract_array_v2_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding.sol b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding.sol new file mode 100644 index 00000000..02937ace --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding.sol @@ -0,0 +1,27 @@ +pragma abicoder v2; +contract Test { + struct MemoryUint { + uint field; + } + function test() public pure returns (uint) { + uint[] memory before = new uint[](1); // at offset 0x80 + // Two problems here: The first offset is zero, the second offset is missing. + bytes memory corrupt = abi.encode(uint(32), // offset to "tuple" + uint(0)); // bogus first element + /* + At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words) + + Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before. + The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where: + x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256) + that is MAX_UINT - 128 + */ + MemoryUint memory afterCorrupt; + afterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80); + before[0] = 123456; + uint[][2] memory decoded = abi.decode(corrupt, (uint[][2])); + return decoded[1][0]; + } +} +// ---- +// test() -> FAILURE diff --git a/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding_standard_input.json b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding_standard_input.json new file mode 100644 index 00000000..291fb254 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding/offset_overflow_in_array_decoding_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + }, + "contract_array_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes calldata x) public returns (C[] memory) {\n return abi.decode(x, (C[]));\n }\n function g() public returns (bytes memory) {\n C[] memory c = new C[](3);\n c[0] = C(address(0x42));\n c[1] = C(address(0x21));\n c[2] = C(address(0x23));\n return abi.encode(c);\n }\n}\n// ----\n// f(bytes): 0x20, 0xA0, 0x20, 3, 0x01, 0x02, 0x03 -> 0x20, 3, 0x01, 0x02, 0x03\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314 -> 0x20, 1, 0x0102030405060708090a0b0c0d0e0f1011121314\n// f(bytes): 0x20, 0x60, 0x20, 1, 0x0102030405060708090a0b0c0d0e0f101112131415 -> FAILURE\n// g() -> 0x20, 0xa0, 0x20, 3, 0x42, 0x21, 0x23\n" + }, + "abi_encode_call_uint_bytes.sol": { + "content": "contract C {\n\tfunction removeSignature(bytes calldata x) external pure returns (bytes memory) {\n\t\treturn x[4:];\n\t}\n\tfunction g(bytes2, bytes2, bytes2) public {}\n\tfunction h(uint16, uint16) public {}\n\tfunction f() public returns (bytes memory) {\n\t\tuint16 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.g, (0x1234, \"ab\", bytes2(x))));\n\t}\n\tfunction f2() public returns (bytes memory) {\n\t\tbytes2 x = 0x1234;\n\t\treturn this.removeSignature(abi.encodeCall(this.h, (0x1234, uint16(x))));\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f() -> 0x20, 0x60, 0x1234000000000000000000000000000000000000000000000000000000000000, 0x6162000000000000000000000000000000000000000000000000000000000000, 0x1234000000000000000000000000000000000000000000000000000000000000\n// f2() -> 0x20, 0x40, 0x1234, 0x1234\n" + }, + "offset_overflow_in_array_decoding.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\t// Two problems here: The first offset is zero, the second offset is missing.\n\t\tbytes memory corrupt = abi.encode(uint(32), // offset to \"tuple\"\n\t\t\t\t\t\t\t\t\t\t uint(0)); // bogus first element\n\t\t/*\n\t\t At this point the free pointer is 0x80 + 64 (size of before) + 32 (length field of corrupt) + 64 (two encoded words)\n\n\t\t Now let's put random junk into memory immediately after the bogus first element. Our goal is to overflow the read pointer to point to before.\n\t\t The value read out at this point will be added to beginning of the encoded tuple, AKA corrupt + 64. We need then to write x where:\n\t\t x + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (first word of corrupt) = 0x80 (mod 2^256)\n\t\t that is MAX_UINT - 128\n\t\t*/\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2.sol b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2.sol new file mode 100644 index 00000000..0a874914 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2.sol @@ -0,0 +1,28 @@ +pragma abicoder v2; +contract Test { + struct MemoryTuple { + uint field1; + uint field2; + } + function withinArray() public pure returns (uint) { + uint[] memory before = new uint[](1); + bytes memory corrupt = abi.encode(uint(32), + uint(2)); + MemoryTuple memory afterCorrupt; + before[0] = 123456; + /* + As above, but in this case we are adding to: + 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer) + giving MAX_UINT - 96 + */ + afterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60); + afterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60); + uint[][] memory decoded = abi.decode(corrupt, (uint[][])); + /* + Will return 123456 * 2, AKA before has been copied twice + */ + return decoded[0][0] + decoded[1][0]; + } +} +// ---- +// withinArray() -> FAILURE diff --git a/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2_standard_input.json b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2_standard_input.json new file mode 100644 index 00000000..472e6bad --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_2/offset_overflow_in_array_decoding_2_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3.sol b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3.sol new file mode 100644 index 00000000..a20e9ae4 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; +contract Test { + struct MemoryUint { + uint field; + } + function test() public pure returns (uint) { + uint[] memory before = new uint[](1); // at offset 0x80 + bytes memory corrupt = abi.encode( + uint(32), + uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80), + uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80) + ); + MemoryUint memory afterCorrupt; + afterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80); + before[0] = 123456; + uint[][2] memory decoded = abi.decode(corrupt, (uint[][2])); + return decoded[1][0]; + } +} +// ---- +// test() -> FAILURE diff --git a/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3_standard_input.json b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3_standard_input.json new file mode 100644 index 00000000..ef5cb0d3 --- /dev/null +++ b/examples/test/semanticTests/abiencodedecode_offset_overflow_in_array_decoding_3/offset_overflow_in_array_decoding_3_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "offset_overflow_in_array_decoding_2.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryTuple {\n\t\tuint field1;\n\t\tuint field2;\n\t}\n\tfunction withinArray() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1);\n\t\tbytes memory corrupt = abi.encode(uint(32),\n\t\t\t\t\t\t\t\t\t\t uint(2));\n\t\tMemoryTuple memory afterCorrupt;\n\t\tbefore[0] = 123456;\n\t\t/*\n\t\t As above, but in this case we are adding to:\n\t\t 0x80 + 64 (before) + 32 (length of corrupt) + 32 (offset) + 32 (field pointer)\n\t\t giving MAX_UINT - 96\n\t\t*/\n\t\tafterCorrupt.field1 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tafterCorrupt.field2 = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60);\n\t\tuint[][] memory decoded = abi.decode(corrupt, (uint[][]));\n\t\t/*\n\t\t Will return 123456 * 2, AKA before has been copied twice\n\t\t */\n\t\treturn decoded[0][0] + decoded[1][0];\n\t}\n}\n// ----\n// withinArray() -> FAILURE\n" + }, + "abi_encode_with_signaturev2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f0() public pure returns (bytes memory) {\n return abi.encodeWithSignature(\"f(uint256)\");\n }\n function f1() public pure returns (bytes memory) {\n string memory x = \"f(uint256)\";\n return abi.encodeWithSignature(x, \"abc\");\n }\n string xstor;\n function f1s() public returns (bytes memory) {\n xstor = \"f(uint256)\";\n return abi.encodeWithSignature(xstor, \"abc\");\n }\n function f2() public pure returns (bytes memory r, uint[] memory ar) {\n string memory x = \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\";\n uint[] memory y = new uint[](4);\n y[0] = type(uint).max;\n y[1] = type(uint).max - 1;\n y[2] = type(uint).max - 2;\n y[3] = type(uint).max - 3;\n r = abi.encodeWithSignature(x, y);\n // The hash uses temporary memory. This allocation re-uses the memory\n // and should initialize it properly.\n ar = new uint[](2);\n }\n struct S { uint a; string b; uint16 c; }\n function f4() public pure returns (bytes memory) {\n S memory s;\n s.a = 0x1234567;\n s.b = \"Lorem ipsum dolor sit ethereum........\";\n s.c = 0x1234;\n return abi.encodeWithSignature(s.b, type(uint).max, s, uint(3));\n }\n}\n// ----\n// f0() -> 0x20, 4, -34435155370463444793260793355178157075203752403645521721995013737368954863616\n// f1() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f1s() -> 0x20, 0x64, -34435155370463444793260793355178157075203752403645521721995013737368954863616, 862718293348820473429344482784628181556388621521298319395315527974912, 91135606241822717681769169345594720818313984248279388438121731325952, 0\n// f2() -> 0x40, 0x0140, 0xc4, -10047825972976160827854069633043429618646681939320956771263895477211642200064, 862718293348820473429344482784628181556388621521298319395315527974912, 0x04ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -1, -26959946667150639794667015087019630673637144422540572481103610249217, -53919893334301279589334030174039261347274288845081144962207220498433, -107839786668602559178668060348078522694548577690162289924414440996864, 2, 0, 0\n// f4() -> 0x20, 292, 0x7c793002ffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -26959946667150639794667015087019630673637144422540572481103610249216, 2588154880046461420288033448353884544669165864563894958185946583924736, 80879840001451919384001045261058892020911433267621717443310830747648, 514631493222945105325971421573240365883976325135760395164659172419450175488, 2588154880046461420288033448353884544669165864563894958185946583924736, 125633351468921981443148290305511478939149093009039067761942823761346560, 0x264c6f72656d20697073756d20646f6c6f722073697420657468657265, 53113508339655873314659021564971517366334151400493876485713881232784043802624, 0\n" + }, + "offset_overflow_in_array_decoding_3.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n\tstruct MemoryUint {\n\t\tuint field;\n\t}\n\tfunction test() public pure returns (uint) {\n\t\tuint[] memory before = new uint[](1); // at offset 0x80\n\t\tbytes memory corrupt = abi.encode(\n uint(32),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80),\n uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80)\n );\n\t\tMemoryUint memory afterCorrupt;\n\t\tafterCorrupt.field = uint(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80);\n\t\tbefore[0] = 123456;\n\t\tuint[][2] memory decoded = abi.decode(corrupt, (uint[][2]));\n\t\treturn decoded[1][0];\n\t}\n}\n// ----\n// test() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable.sol b/examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable.sol new file mode 100644 index 00000000..b8def588 --- /dev/null +++ b/examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable.sol @@ -0,0 +1,5 @@ +contract Lotto { + uint256 public constant ticketPrice = 555; +} +// ---- +// ticketPrice() -> 555 diff --git a/examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable_standard_input.json b/examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable_standard_input.json new file mode 100644 index 00000000..a4ef23f5 --- /dev/null +++ b/examples/test/semanticTests/accessor_accessor_for_const_state_variable/accessor_for_const_state_variable_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "accessor_for_state_variable.sol": { + "content": "contract Lotto {\n uint256 public ticketPrice = 500;\n}\n// ----\n// ticketPrice() -> 500\n" + }, + "accessor_for_const_state_variable.sol": { + "content": "contract Lotto {\n uint256 public constant ticketPrice = 555;\n}\n// ----\n// ticketPrice() -> 555\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable.sol b/examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable.sol new file mode 100644 index 00000000..51cb8e5e --- /dev/null +++ b/examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable.sol @@ -0,0 +1,5 @@ +contract Lotto { + uint256 public ticketPrice = 500; +} +// ---- +// ticketPrice() -> 500 diff --git a/examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable_standard_input.json b/examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable_standard_input.json new file mode 100644 index 00000000..65c4161c --- /dev/null +++ b/examples/test/semanticTests/accessor_accessor_for_state_variable/accessor_for_state_variable_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "accessor_for_state_variable.sol": { + "content": "contract Lotto {\n uint256 public ticketPrice = 500;\n}\n// ----\n// ticketPrice() -> 500\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod.sol b/examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod.sol new file mode 100644 index 00000000..e6f703bd --- /dev/null +++ b/examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod.sol @@ -0,0 +1,11 @@ +contract C { + function test() public returns (uint256) { + // Note that this only works because computation on literals is done using + // unbounded integers. + if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1; + if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2; + return 0; + } +} +// ---- +// test() -> 0 diff --git a/examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod_standard_input.json b/examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod_standard_input.json new file mode 100644 index 00000000..1e96babe --- /dev/null +++ b/examples/test/semanticTests/arithmetics_addmod_mulmod/addmod_mulmod_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero.sol b/examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero.sol new file mode 100644 index 00000000..cd32ceff --- /dev/null +++ b/examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero.sol @@ -0,0 +1,23 @@ +contract C { + function f(uint256 d) public pure returns (uint256) { + addmod(1, 2, d); + return 2; + } + + function g(uint256 d) public pure returns (uint256) { + mulmod(1, 2, d); + return 2; + } + + function h() public pure returns (uint256) { + mulmod(0, 1, 2); + mulmod(1, 0, 2); + addmod(0, 1, 2); + addmod(1, 0, 2); + return 2; + } +} +// ---- +// f(uint256): 0 -> FAILURE, hex"4e487b71", 0x12 +// g(uint256): 0 -> FAILURE, hex"4e487b71", 0x12 +// h() -> 2 diff --git a/examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero_standard_input.json b/examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero_standard_input.json new file mode 100644 index 00000000..fa13abcb --- /dev/null +++ b/examples/test/semanticTests/arithmetics_addmod_mulmod_zero/addmod_mulmod_zero_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod_zero.sol": { + "content": "contract C {\n function f(uint256 d) public pure returns (uint256) {\n addmod(1, 2, d);\n return 2;\n }\n\n function g(uint256 d) public pure returns (uint256) {\n mulmod(1, 2, d);\n return 2;\n }\n\n function h() public pure returns (uint256) {\n mulmod(0, 1, 2);\n mulmod(1, 0, 2);\n addmod(0, 1, 2);\n addmod(1, 0, 2);\n return 2;\n }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked.sol b/examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked.sol new file mode 100644 index 00000000..7a8504d5 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint y) { + unchecked{{ + uint max = type(uint).max; + uint x = max + 1; + y = x; + }} + } +} +// ---- +// f() -> 0x00 diff --git a/examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked_standard_input.json b/examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked_standard_input.json new file mode 100644 index 00000000..d8b79f0b --- /dev/null +++ b/examples/test/semanticTests/arithmetics_block_inside_unchecked/block_inside_unchecked_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_check_var_init/check_var_init.sol b/examples/test/semanticTests/arithmetics_check_var_init/check_var_init.sol new file mode 100644 index 00000000..9061cd28 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_check_var_init/check_var_init.sol @@ -0,0 +1,20 @@ +contract C { + uint public x = msg.value - 10; + constructor() payable {} +} + +contract D { + function f() public { + unchecked { + new C(); + } + } + function g() public payable returns (uint) { + return (new C{value: 11}()).x(); + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x11 +// g(), 100 wei -> 1 +// gas legacy: 76780 +// gas legacy code: 23600 diff --git a/examples/test/semanticTests/arithmetics_check_var_init/check_var_init_standard_input.json b/examples/test/semanticTests/arithmetics_check_var_init/check_var_init_standard_input.json new file mode 100644 index 00000000..060cab6d --- /dev/null +++ b/examples/test/semanticTests/arithmetics_check_var_init/check_var_init_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod_zero.sol": { + "content": "contract C {\n function f(uint256 d) public pure returns (uint256) {\n addmod(1, 2, d);\n return 2;\n }\n\n function g(uint256 d) public pure returns (uint256) {\n mulmod(1, 2, d);\n return 2;\n }\n\n function h() public pure returns (uint256) {\n mulmod(0, 1, 2);\n mulmod(1, 0, 2);\n addmod(0, 1, 2);\n addmod(1, 0, 2);\n return 2;\n }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n" + }, + "check_var_init.sol": { + "content": "contract C {\n uint public x = msg.value - 10;\n constructor() payable {}\n}\n\ncontract D {\n function f() public {\n unchecked {\n new C();\n }\n }\n function g() public payable returns (uint) {\n return (new C{value: 11}()).x();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n// g(), 100 wei -> 1\n// gas legacy: 76780\n// gas legacy code: 23600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1.sol b/examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1.sol new file mode 100644 index 00000000..03c2bb56 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +contract C { + // Input is still not checked - this needs ABIEncoderV2! + function f(uint16 a, uint16 b) public returns (uint16) { + return a + b; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(uint16,uint16): 65534, 0 -> 0xfffe +// f(uint16,uint16): 65536, 0 -> 0x00 +// f(uint16,uint16): 65535, 0 -> 0xffff +// f(uint16,uint16): 65535, 1 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1_standard_input.json b/examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1_standard_input.json new file mode 100644 index 00000000..79605984 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_add_v1/checked_add_v1_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2.sol b/examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2.sol new file mode 100644 index 00000000..8a29cb2b --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; +contract C { + function f(uint16 a, uint16 b) public returns (uint16) { + return a + b; + } +} +// ---- +// f(uint16,uint16): 65534, 0 -> 0xfffe +// f(uint16,uint16): 65536, 0 -> FAILURE +// f(uint16,uint16): 65535, 0 -> 0xffff +// f(uint16,uint16): 65535, 1 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2_standard_input.json b/examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2_standard_input.json new file mode 100644 index 00000000..94702cbf --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_add_v2/checked_add_v2_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked.sol b/examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked.sol new file mode 100644 index 00000000..420a52cd --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked.sol @@ -0,0 +1,12 @@ +contract C { + function add(uint16 a, uint16 b) public returns (uint16) { + return a + b; + } + + function f(uint16 a, uint16 b, uint16 c) public returns (uint16) { + unchecked { return add(a, b) + c; } + } +} +// ---- +// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(uint16,uint16,uint16): 0xe000, 0x1000, 0x1000 -> 0x00 diff --git a/examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked_standard_input.json b/examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked_standard_input.json new file mode 100644 index 00000000..ace6c37b --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_called_by_unchecked/checked_called_by_unchecked_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod_zero.sol": { + "content": "contract C {\n function f(uint256 d) public pure returns (uint256) {\n addmod(1, 2, d);\n return 2;\n }\n\n function g(uint256 d) public pure returns (uint256) {\n mulmod(1, 2, d);\n return 2;\n }\n\n function h() public pure returns (uint256) {\n mulmod(0, 1, 2);\n mulmod(1, 0, 2);\n addmod(0, 1, 2);\n addmod(1, 0, 2);\n return 2;\n }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n" + }, + "check_var_init.sol": { + "content": "contract C {\n uint public x = msg.value - 10;\n constructor() payable {}\n}\n\ncontract D {\n function f() public {\n unchecked {\n new C();\n }\n }\n function g() public payable returns (uint) {\n return (new C{value: 11}()).x();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n// g(), 100 wei -> 1\n// gas legacy: 76780\n// gas legacy code: 23600\n" + }, + "signed_mod.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int) {\n return a % b;\n }\n function g(bool _check) public pure returns (int) {\n int x = type(int).min;\n if (_check) {\n return x / -1;\n } else {\n unchecked { return x / -1; }\n }\n }\n}\n// ----\n// f(int256,int256): 7, 5 -> 2\n// f(int256,int256): 7, -5 -> 2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -5, -5 -> 0\n// g(bool): true -> FAILURE, hex\"4e487b71\", 0x11\n// g(bool): false -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + }, + "exp_associativity.sol": { + "content": "contract C {\n // (2**3)**4 = 4096\n // 2**(3**4) = 2417851639229258349412352\n function test_hardcode1(uint a, uint b, uint c) public returns (uint256) {\n return a**b**c;\n }\n\n // (3**2)**2)**2 = 6561\n // 3**(2**(2**2) = 43046721\n function test_hardcode2(uint a, uint b, uint c, uint d) public returns (uint256) {\n return a**b**c**d;\n }\n\n function test_invariant(uint a, uint b, uint c) public returns (bool) {\n return a**b**c == a**(b**c);\n }\n\n function test_literal_mix(uint a, uint b) public returns (bool) {\n return\n (a**2**b == a**(2**b)) &&\n (2**a**b == 2**(a**b)) &&\n (a**b**2 == a**(b**2));\n }\n\n function test_other_operators(uint a, uint b) public returns (bool) {\n return\n (a**b/25 == (a**b)/25) &&\n (a**b*3**b == (a**b)*(3**b)) &&\n (b**a**a/b**a**b == (b**(a**a))/(b**(a**b)));\n }\n}\n// ----\n// test_hardcode1(uint256,uint256,uint256): 2, 3, 4 -> 2417851639229258349412352\n// test_hardcode2(uint256,uint256,uint256,uint256): 3, 2, 2, 2 -> 43046721\n// test_invariant(uint256,uint256,uint256): 2, 3, 4 -> true\n// test_invariant(uint256,uint256,uint256): 3, 4, 2 -> true\n// test_literal_mix(uint256,uint256): 2, 3 -> true\n// test_other_operators(uint256,uint256): 2, 4 -> true\n" + }, + "checked_called_by_unchecked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public returns (uint16) {\n unchecked { return add(a, b) + c; }\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint16,uint16,uint16): 0xe000, 0x1000, 0x1000 -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked.sol b/examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked.sol new file mode 100644 index 00000000..42658f83 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked.sol @@ -0,0 +1,13 @@ +contract C { + modifier add(uint16 a, uint16 b) { + unchecked { a + b; } + _; + } + + function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) { + return b + c; + } +} +// ---- +// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626 +// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked_standard_input.json b/examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked_standard_input.json new file mode 100644 index 00000000..f774f247 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_checked_modifier_called_by_unchecked/checked_modifier_called_by_unchecked_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero.sol b/examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero.sol new file mode 100644 index 00000000..517c4966 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero.sol @@ -0,0 +1,14 @@ +contract C { + function div(uint256 a, uint256 b) public returns (uint256) { + return a / b; + } + + function mod(uint256 a, uint256 b) public returns (uint256) { + return a % b; + } +} +// ---- +// div(uint256,uint256): 7, 2 -> 3 +// div(uint256,uint256): 7, 0 -> FAILURE, hex"4e487b71", 0x12 # throws # +// mod(uint256,uint256): 7, 2 -> 1 +// mod(uint256,uint256): 7, 0 -> FAILURE, hex"4e487b71", 0x12 # throws # diff --git a/examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero_standard_input.json b/examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero_standard_input.json new file mode 100644 index 00000000..ccc463ad --- /dev/null +++ b/examples/test/semanticTests/arithmetics_divisiod_by_zero/divisiod_by_zero_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod_zero.sol": { + "content": "contract C {\n function f(uint256 d) public pure returns (uint256) {\n addmod(1, 2, d);\n return 2;\n }\n\n function g(uint256 d) public pure returns (uint256) {\n mulmod(1, 2, d);\n return 2;\n }\n\n function h() public pure returns (uint256) {\n mulmod(0, 1, 2);\n mulmod(1, 0, 2);\n addmod(0, 1, 2);\n addmod(1, 0, 2);\n return 2;\n }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n" + }, + "check_var_init.sol": { + "content": "contract C {\n uint public x = msg.value - 10;\n constructor() payable {}\n}\n\ncontract D {\n function f() public {\n unchecked {\n new C();\n }\n }\n function g() public payable returns (uint) {\n return (new C{value: 11}()).x();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n// g(), 100 wei -> 1\n// gas legacy: 76780\n// gas legacy code: 23600\n" + }, + "signed_mod.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int) {\n return a % b;\n }\n function g(bool _check) public pure returns (int) {\n int x = type(int).min;\n if (_check) {\n return x / -1;\n } else {\n unchecked { return x / -1; }\n }\n }\n}\n// ----\n// f(int256,int256): 7, 5 -> 2\n// f(int256,int256): 7, -5 -> 2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -5, -5 -> 0\n// g(bool): true -> FAILURE, hex\"4e487b71\", 0x11\n// g(bool): false -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + }, + "exp_associativity.sol": { + "content": "contract C {\n // (2**3)**4 = 4096\n // 2**(3**4) = 2417851639229258349412352\n function test_hardcode1(uint a, uint b, uint c) public returns (uint256) {\n return a**b**c;\n }\n\n // (3**2)**2)**2 = 6561\n // 3**(2**(2**2) = 43046721\n function test_hardcode2(uint a, uint b, uint c, uint d) public returns (uint256) {\n return a**b**c**d;\n }\n\n function test_invariant(uint a, uint b, uint c) public returns (bool) {\n return a**b**c == a**(b**c);\n }\n\n function test_literal_mix(uint a, uint b) public returns (bool) {\n return\n (a**2**b == a**(2**b)) &&\n (2**a**b == 2**(a**b)) &&\n (a**b**2 == a**(b**2));\n }\n\n function test_other_operators(uint a, uint b) public returns (bool) {\n return\n (a**b/25 == (a**b)/25) &&\n (a**b*3**b == (a**b)*(3**b)) &&\n (b**a**a/b**a**b == (b**(a**a))/(b**(a**b)));\n }\n}\n// ----\n// test_hardcode1(uint256,uint256,uint256): 2, 3, 4 -> 2417851639229258349412352\n// test_hardcode2(uint256,uint256,uint256,uint256): 3, 2, 2, 2 -> 43046721\n// test_invariant(uint256,uint256,uint256): 2, 3, 4 -> true\n// test_invariant(uint256,uint256,uint256): 3, 4, 2 -> true\n// test_literal_mix(uint256,uint256): 2, 3 -> true\n// test_other_operators(uint256,uint256): 2, 4 -> true\n" + }, + "checked_called_by_unchecked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public returns (uint16) {\n unchecked { return add(a, b) + c; }\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint16,uint16,uint16): 0xe000, 0x1000, 0x1000 -> 0x00\n" + }, + "divisiod_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n return a / b;\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n return a % b;\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity.sol b/examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity.sol new file mode 100644 index 00000000..0ec9f2c7 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity.sol @@ -0,0 +1,38 @@ +contract C { + // (2**3)**4 = 4096 + // 2**(3**4) = 2417851639229258349412352 + function test_hardcode1(uint a, uint b, uint c) public returns (uint256) { + return a**b**c; + } + + // (3**2)**2)**2 = 6561 + // 3**(2**(2**2) = 43046721 + function test_hardcode2(uint a, uint b, uint c, uint d) public returns (uint256) { + return a**b**c**d; + } + + function test_invariant(uint a, uint b, uint c) public returns (bool) { + return a**b**c == a**(b**c); + } + + function test_literal_mix(uint a, uint b) public returns (bool) { + return + (a**2**b == a**(2**b)) && + (2**a**b == 2**(a**b)) && + (a**b**2 == a**(b**2)); + } + + function test_other_operators(uint a, uint b) public returns (bool) { + return + (a**b/25 == (a**b)/25) && + (a**b*3**b == (a**b)*(3**b)) && + (b**a**a/b**a**b == (b**(a**a))/(b**(a**b))); + } +} +// ---- +// test_hardcode1(uint256,uint256,uint256): 2, 3, 4 -> 2417851639229258349412352 +// test_hardcode2(uint256,uint256,uint256,uint256): 3, 2, 2, 2 -> 43046721 +// test_invariant(uint256,uint256,uint256): 2, 3, 4 -> true +// test_invariant(uint256,uint256,uint256): 3, 4, 2 -> true +// test_literal_mix(uint256,uint256): 2, 3 -> true +// test_other_operators(uint256,uint256): 2, 4 -> true diff --git a/examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity_standard_input.json b/examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity_standard_input.json new file mode 100644 index 00000000..b75e7486 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_exp_associativity/exp_associativity_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod_zero.sol": { + "content": "contract C {\n function f(uint256 d) public pure returns (uint256) {\n addmod(1, 2, d);\n return 2;\n }\n\n function g(uint256 d) public pure returns (uint256) {\n mulmod(1, 2, d);\n return 2;\n }\n\n function h() public pure returns (uint256) {\n mulmod(0, 1, 2);\n mulmod(1, 0, 2);\n addmod(0, 1, 2);\n addmod(1, 0, 2);\n return 2;\n }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n" + }, + "check_var_init.sol": { + "content": "contract C {\n uint public x = msg.value - 10;\n constructor() payable {}\n}\n\ncontract D {\n function f() public {\n unchecked {\n new C();\n }\n }\n function g() public payable returns (uint) {\n return (new C{value: 11}()).x();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n// g(), 100 wei -> 1\n// gas legacy: 76780\n// gas legacy code: 23600\n" + }, + "signed_mod.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int) {\n return a % b;\n }\n function g(bool _check) public pure returns (int) {\n int x = type(int).min;\n if (_check) {\n return x / -1;\n } else {\n unchecked { return x / -1; }\n }\n }\n}\n// ----\n// f(int256,int256): 7, 5 -> 2\n// f(int256,int256): 7, -5 -> 2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -5, -5 -> 0\n// g(bool): true -> FAILURE, hex\"4e487b71\", 0x11\n// g(bool): false -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + }, + "exp_associativity.sol": { + "content": "contract C {\n // (2**3)**4 = 4096\n // 2**(3**4) = 2417851639229258349412352\n function test_hardcode1(uint a, uint b, uint c) public returns (uint256) {\n return a**b**c;\n }\n\n // (3**2)**2)**2 = 6561\n // 3**(2**(2**2) = 43046721\n function test_hardcode2(uint a, uint b, uint c, uint d) public returns (uint256) {\n return a**b**c**d;\n }\n\n function test_invariant(uint a, uint b, uint c) public returns (bool) {\n return a**b**c == a**(b**c);\n }\n\n function test_literal_mix(uint a, uint b) public returns (bool) {\n return\n (a**2**b == a**(2**b)) &&\n (2**a**b == 2**(a**b)) &&\n (a**b**2 == a**(b**2));\n }\n\n function test_other_operators(uint a, uint b) public returns (bool) {\n return\n (a**b/25 == (a**b)/25) &&\n (a**b*3**b == (a**b)*(3**b)) &&\n (b**a**a/b**a**b == (b**(a**a))/(b**(a**b)));\n }\n}\n// ----\n// test_hardcode1(uint256,uint256,uint256): 2, 3, 4 -> 2417851639229258349412352\n// test_hardcode2(uint256,uint256,uint256,uint256): 3, 2, 2, 2 -> 43046721\n// test_invariant(uint256,uint256,uint256): 2, 3, 4 -> true\n// test_invariant(uint256,uint256,uint256): 3, 4, 2 -> true\n// test_literal_mix(uint256,uint256): 2, 3 -> true\n// test_other_operators(uint256,uint256): 2, 4 -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_signed_mod/signed_mod.sol b/examples/test/semanticTests/arithmetics_signed_mod/signed_mod.sol new file mode 100644 index 00000000..30625620 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_signed_mod/signed_mod.sol @@ -0,0 +1,21 @@ +contract C { + function f(int a, int b) public pure returns (int) { + return a % b; + } + function g(bool _check) public pure returns (int) { + int x = type(int).min; + if (_check) { + return x / -1; + } else { + unchecked { return x / -1; } + } + } +} +// ---- +// f(int256,int256): 7, 5 -> 2 +// f(int256,int256): 7, -5 -> 2 +// f(int256,int256): -7, 5 -> -2 +// f(int256,int256): -7, 5 -> -2 +// f(int256,int256): -5, -5 -> 0 +// g(bool): true -> FAILURE, hex"4e487b71", 0x11 +// g(bool): false -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 diff --git a/examples/test/semanticTests/arithmetics_signed_mod/signed_mod_standard_input.json b/examples/test/semanticTests/arithmetics_signed_mod/signed_mod_standard_input.json new file mode 100644 index 00000000..52012e6d --- /dev/null +++ b/examples/test/semanticTests/arithmetics_signed_mod/signed_mod_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + }, + "checked_add_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> FAILURE\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_add_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n // Input is still not checked - this needs ABIEncoderV2!\n function f(uint16 a, uint16 b) public returns (uint16) {\n return a + b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint16,uint16): 65534, 0 -> 0xfffe\n// f(uint16,uint16): 65536, 0 -> 0x00\n// f(uint16,uint16): 65535, 0 -> 0xffff\n// f(uint16,uint16): 65535, 1 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "checked_modifier_called_by_unchecked.sol": { + "content": "contract C {\n modifier add(uint16 a, uint16 b) {\n unchecked { a + b; }\n _;\n }\n\n function f(uint16 a, uint16 b, uint16 c) public add(a, b) returns (uint16) {\n return b + c;\n }\n}\n// ----\n// f(uint16,uint16,uint16): 0xe000, 0xe500, 2 -> 58626\n// f(uint16,uint16,uint16): 0x1000, 0xe500, 0xe000 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod_zero.sol": { + "content": "contract C {\n function f(uint256 d) public pure returns (uint256) {\n addmod(1, 2, d);\n return 2;\n }\n\n function g(uint256 d) public pure returns (uint256) {\n mulmod(1, 2, d);\n return 2;\n }\n\n function h() public pure returns (uint256) {\n mulmod(0, 1, 2);\n mulmod(1, 0, 2);\n addmod(0, 1, 2);\n addmod(1, 0, 2);\n return 2;\n }\n}\n// ----\n// f(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint256): 0 -> FAILURE, hex\"4e487b71\", 0x12\n// h() -> 2\n" + }, + "check_var_init.sol": { + "content": "contract C {\n uint public x = msg.value - 10;\n constructor() payable {}\n}\n\ncontract D {\n function f() public {\n unchecked {\n new C();\n }\n }\n function g() public payable returns (uint) {\n return (new C{value: 11}()).x();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x11\n// g(), 100 wei -> 1\n// gas legacy: 76780\n// gas legacy code: 23600\n" + }, + "signed_mod.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int) {\n return a % b;\n }\n function g(bool _check) public pure returns (int) {\n int x = type(int).min;\n if (_check) {\n return x / -1;\n } else {\n unchecked { return x / -1; }\n }\n }\n}\n// ----\n// f(int256,int256): 7, 5 -> 2\n// f(int256,int256): 7, -5 -> 2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -7, 5 -> -2\n// f(int256,int256): -5, -5 -> 0\n// g(bool): true -> FAILURE, hex\"4e487b71\", 0x11\n// g(bool): false -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked.sol b/examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked.sol new file mode 100644 index 00000000..14050627 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked.sol @@ -0,0 +1,15 @@ +contract C { + function add(uint16 a, uint16 b) public returns (uint16) { + unchecked { + return a + b; + } + } + + function f(uint16 a) public returns (uint16) { + return add(a, 0x100) + 0x100; + } +} +// ---- +// f(uint16): 7 -> 0x0207 +// f(uint16): 0xffff -> 511 +// f(uint16): 0xfeff -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked_standard_input.json b/examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked_standard_input.json new file mode 100644 index 00000000..c09c9680 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_unchecked_called_by_checked/unchecked_called_by_checked_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero.sol b/examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero.sol new file mode 100644 index 00000000..ae91ea27 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero.sol @@ -0,0 +1,20 @@ +contract C { + function div(uint256 a, uint256 b) public returns (uint256) { + // Does not disable div by zero check + unchecked { + return a / b; + } + } + + function mod(uint256 a, uint256 b) public returns (uint256) { + // Does not disable div by zero check + unchecked { + return a % b; + } + } +} +// ---- +// div(uint256,uint256): 7, 2 -> 3 +// div(uint256,uint256): 7, 0 -> FAILURE, hex"4e487b71", 0x12 # throws # +// mod(uint256,uint256): 7, 2 -> 1 +// mod(uint256,uint256): 7, 0 -> FAILURE, hex"4e487b71", 0x12 # throws # diff --git a/examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero_standard_input.json b/examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero_standard_input.json new file mode 100644 index 00000000..94f95ac6 --- /dev/null +++ b/examples/test/semanticTests/arithmetics_unchecked_div_by_zero/unchecked_div_by_zero_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "unchecked_called_by_checked.sol": { + "content": "contract C {\n function add(uint16 a, uint16 b) public returns (uint16) {\n unchecked {\n return a + b;\n }\n }\n\n function f(uint16 a) public returns (uint16) {\n return add(a, 0x100) + 0x100;\n }\n}\n// ----\n// f(uint16): 7 -> 0x0207\n// f(uint16): 0xffff -> 511\n// f(uint16): 0xfeff -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "addmod_mulmod.sol": { + "content": "contract C {\n function test() public returns (uint256) {\n // Note that this only works because computation on literals is done using\n // unbounded integers.\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 1;\n if ((2**255 + 2**255) % 7 != addmod(2**255, 2**255, 7)) return 2;\n return 0;\n }\n}\n// ----\n// test() -> 0\n" + }, + "block_inside_unchecked.sol": { + "content": "contract C {\n function f() public returns (uint y) {\n unchecked{{\n uint max = type(uint).max;\n uint x = max + 1;\n y = x;\n }}\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "unchecked_div_by_zero.sol": { + "content": "contract C {\n function div(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a / b;\n }\n }\n\n function mod(uint256 a, uint256 b) public returns (uint256) {\n // Does not disable div by zero check\n unchecked {\n return a % b;\n }\n }\n}\n// ----\n// div(uint256,uint256): 7, 2 -> 3\n// div(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n// mod(uint256,uint256): 7, 2 -> 1\n// mod(uint256,uint256): 7, 0 -> FAILURE, hex\"4e487b71\", 0x12 # throws #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment.sol b/examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment.sol new file mode 100644 index 00000000..9a4093c3 --- /dev/null +++ b/examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment.sol @@ -0,0 +1,12 @@ +contract C { + function f(uint n) public pure returns (uint) { + uint[][] memory a = new uint[][](2); + for (uint i = 0; i < 2; ++i) + a[i] = new uint[](3); + a[1][1] = n; + uint[] memory b = a[1]; + return b[1]; + } +} +// ---- +// f(uint256): 42 -> 42 diff --git a/examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment_standard_input.json b/examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment_standard_input.json new file mode 100644 index 00000000..fab537c3 --- /dev/null +++ b/examples/test/semanticTests/array_array_2d_assignment/array_2d_assignment_standard_input.json @@ -0,0 +1,193 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_2d_new/array_2d_new.sol b/examples/test/semanticTests/array_array_2d_new/array_2d_new.sol new file mode 100644 index 00000000..13c0ac20 --- /dev/null +++ b/examples/test/semanticTests/array_array_2d_new/array_2d_new.sol @@ -0,0 +1,10 @@ +contract C { + function f(uint n) public pure returns (uint) { + uint[][] memory a = new uint[][](2); + for (uint i = 0; i < 2; ++i) + a[i] = new uint[](3); + return a[0][0] = n; + } +} +// ---- +// f(uint256): 42 -> 42 diff --git a/examples/test/semanticTests/array_array_2d_new/array_2d_new_standard_input.json b/examples/test/semanticTests/array_array_2d_new/array_2d_new_standard_input.json new file mode 100644 index 00000000..bf230cab --- /dev/null +++ b/examples/test/semanticTests/array_array_2d_new/array_2d_new_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment.sol b/examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment.sol new file mode 100644 index 00000000..f987a17d --- /dev/null +++ b/examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment.sol @@ -0,0 +1,17 @@ +contract C { + function f(uint n) public pure returns (uint) { + uint[][][] memory a = new uint[][][](2); + for (uint i = 0; i < 2; ++i) + { + a[i] = new uint[][](3); + for (uint j = 0; j < 3; ++j) + a[i][j] = new uint[](4); + } + a[1][1][1] = n; + uint[][] memory b = a[1]; + uint[] memory c = b[1]; + return c[1]; + } +} +// ---- +// f(uint256): 42 -> 42 diff --git a/examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment_standard_input.json b/examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment_standard_input.json new file mode 100644 index 00000000..a017bd5d --- /dev/null +++ b/examples/test/semanticTests/array_array_3d_assignment/array_3d_assignment_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_3d_new/array_3d_new.sol b/examples/test/semanticTests/array_array_3d_new/array_3d_new.sol new file mode 100644 index 00000000..b4bb4e62 --- /dev/null +++ b/examples/test/semanticTests/array_array_3d_new/array_3d_new.sol @@ -0,0 +1,14 @@ +contract C { + function f(uint n) public pure returns (uint) { + uint[][][] memory a = new uint[][][](2); + for (uint i = 0; i < 2; ++i) + { + a[i] = new uint[][](3); + for (uint j = 0; j < 3; ++j) + a[i][j] = new uint[](4); + } + return a[1][1][1] = n; + } +} +// ---- +// f(uint256): 42 -> 42 diff --git a/examples/test/semanticTests/array_array_3d_new/array_3d_new_standard_input.json b/examples/test/semanticTests/array_array_3d_new/array_3d_new_standard_input.json new file mode 100644 index 00000000..695c6513 --- /dev/null +++ b/examples/test/semanticTests/array_array_3d_new/array_3d_new_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_function_pointers/array_function_pointers.sol b/examples/test/semanticTests/array_array_function_pointers/array_function_pointers.sol new file mode 100644 index 00000000..5d4707ec --- /dev/null +++ b/examples/test/semanticTests/array_array_function_pointers/array_function_pointers.sol @@ -0,0 +1,27 @@ +contract C { + function f(uint n, uint m) public { + function() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n); + arr[m](); + } + function f2(uint n, uint m, uint a, uint b) public { + function() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n); + for (uint i = 0; i < n; ++i) + arr[i] = new function() internal returns (uint)[](m); + arr[a][b](); + } + function g(uint n, uint m) public { + function() external returns (uint)[] memory arr = new function() external returns (uint)[](n); + arr[m](); + } + function g2(uint n, uint m, uint a, uint b) public { + function() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n); + for (uint i = 0; i < n; ++i) + arr[i] = new function() external returns (uint)[](m); + arr[a][b](); + } +} +// ---- +// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas # +// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas # +// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas # +// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas # diff --git a/examples/test/semanticTests/array_array_function_pointers/array_function_pointers_standard_input.json b/examples/test/semanticTests/array_array_function_pointers/array_function_pointers_standard_input.json new file mode 100644 index 00000000..13e925f5 --- /dev/null +++ b/examples/test/semanticTests/array_array_function_pointers/array_function_pointers_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access.sol b/examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access.sol new file mode 100644 index 00000000..683eca90 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access.sol @@ -0,0 +1,22 @@ +contract C { + uint test1; + uint test2; + uint test3; + uint test4; + uint test5; + uint test6; + uint test7; + mapping (string => uint) map; + function set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) { + map[s] = 0; + uint[][] memory x = new uint[][](n); + for (uint i = 0; i < n; ++i) + x[i] = new uint[](m); + return x[a][b]; + } +} +// ---- +// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, "01234567890123456789012345678901" -> FAILURE, hex"4e487b71", 0x32 +// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, "01234567890123456789012345678901" -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access_standard_input.json b/examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access_standard_input.json new file mode 100644 index 00000000..118075cc --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_2d_zeroed_memory_index_access/array_2d_zeroed_memory_index_access_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "array_static_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[3] memory x;\n\t\treturn x[2];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0\n" + }, + "array_2d_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[][] memory x = new uint[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tx[i] = new uint[](m);\n\t\treturn x[a][b];\n\t}\n}\n// ----\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static.sol b/examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static.sol new file mode 100644 index 00000000..6113cfee --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static.sol @@ -0,0 +1,20 @@ +contract C { + uint test1; + uint test2; + uint test3; + uint test4; + uint test5; + uint test6; + uint test7; + mapping (string => uint) map; + function set(string memory s, uint n, uint m) public returns (uint) { + map[s] = 0; + uint[4][] memory x = new uint[4][](n); + return x[m][0]; + } +} +// ---- +// set(string,uint256,uint256): 0x60, 2, 0, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256): 0x60, 2, 1, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256): 0x60, 2, 2, 32, "01234567890123456789012345678901" -> FAILURE, hex"4e487b71", 0x32 +// set(string,uint256,uint256): 0x60, 200, 199, 32, "01234567890123456789012345678901" -> 0 diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static_standard_input.json b/examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static_standard_input.json new file mode 100644 index 00000000..05ba70bd --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_array_static/array_array_static_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "array_static_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[3] memory x;\n\t\treturn x[2];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0\n" + }, + "array_2d_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[][] memory x = new uint[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tx[i] = new uint[](m);\n\t\treturn x[a][b];\n\t}\n}\n// ----\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint a) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[] memory x = new uint[](n);\n\t\treturn x[a];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 5, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 4, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_array_static.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[4][] memory x = new uint[4][](n);\n\t\treturn x[m][0];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 2, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 2, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 2, 2, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256): 0x60, 200, 199, 32, \"01234567890123456789012345678901\" -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access.sol b/examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access.sol new file mode 100644 index 00000000..13af18a5 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access.sol @@ -0,0 +1,15 @@ +contract C { + uint test1; + uint test2; + uint test3; + uint test4; + uint test5; + uint test6; + uint test7; + mapping (string => uint) map; + function set(string memory s) public returns (uint[3] memory x, uint[2] memory y, uint[] memory z, uint t) { + map[s] = 0; + } +} +// ---- +// set(string): 0x20, 32, "01234567890123456789012345678901" -> 0, 0, 0, 0, 0, 0xe0, 0, 0 diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access_standard_input.json b/examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access_standard_input.json new file mode 100644 index 00000000..1609a0b8 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_static_return_param_zeroed_memory_index_access/array_static_return_param_zeroed_memory_index_access_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "array_static_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[3] memory x;\n\t\treturn x[2];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0\n" + }, + "array_2d_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[][] memory x = new uint[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tx[i] = new uint[](m);\n\t\treturn x[a][b];\n\t}\n}\n// ----\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint a) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[] memory x = new uint[](n);\n\t\treturn x[a];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 5, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 4, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_array_static.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[4][] memory x = new uint[4][](n);\n\t\treturn x[m][0];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 2, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 2, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 2, 2, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256): 0x60, 200, 199, 32, \"01234567890123456789012345678901\" -> 0\n" + }, + "array_static_return_param_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint[3] memory x, uint[2] memory y, uint[] memory z, uint t) {\n\t\tmap[s] = 0;\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0, 0, 0, 0, 0, 0xe0, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access.sol b/examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access.sol new file mode 100644 index 00000000..eddf0e72 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access.sol @@ -0,0 +1,17 @@ +contract C { + uint test1; + uint test2; + uint test3; + uint test4; + uint test5; + uint test6; + uint test7; + mapping (string => uint) map; + function set(string memory s) public returns (uint) { + map[s] = 0; + uint[3] memory x; + return x[2]; + } +} +// ---- +// set(string): 0x20, 32, "01234567890123456789012345678901" -> 0 diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access_standard_input.json b/examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access_standard_input.json new file mode 100644 index 00000000..75003909 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_static_zeroed_memory_index_access/array_static_zeroed_memory_index_access_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "array_static_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[3] memory x;\n\t\treturn x[2];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access.sol b/examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access.sol new file mode 100644 index 00000000..5eeaad7d --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access.sol @@ -0,0 +1,20 @@ +contract C { + uint test1; + uint test2; + uint test3; + uint test4; + uint test5; + uint test6; + uint test7; + mapping (string => uint) map; + function set(string memory s, uint n, uint a) public returns (uint) { + map[s] = 0; + uint[] memory x = new uint[](n); + return x[a]; + } +} +// ---- +// set(string,uint256,uint256): 0x60, 5, 0, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256): 0x60, 5, 1, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256): 0x60, 5, 4, 32, "01234567890123456789012345678901" -> 0 +// set(string,uint256,uint256): 0x60, 5, 5, 32, "01234567890123456789012345678901" -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access_standard_input.json b/examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access_standard_input.json new file mode 100644 index 00000000..759414fc --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_allocation_array_zeroed_memory_index_access/array_zeroed_memory_index_access_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "array_static_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[3] memory x;\n\t\treturn x[2];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" -> 0\n" + }, + "array_2d_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint m, uint a, uint b) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[][] memory x = new uint[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tx[i] = new uint[](m);\n\t\treturn x[a][b];\n\t}\n}\n// ----\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 0, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 3, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 3, 3, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n// set(string,uint256,uint256,uint256,uint256): 0xa0, 2, 4, 1, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_zeroed_memory_index_access.sol": { + "content": "contract C {\n\tuint test1;\n\tuint test2;\n\tuint test3;\n\tuint test4;\n\tuint test5;\n\tuint test6;\n\tuint test7;\n\tmapping (string => uint) map;\n\tfunction set(string memory s, uint n, uint a) public returns (uint) {\n\t\tmap[s] = 0;\n\t\tuint[] memory x = new uint[](n);\n\t\treturn x[a];\n\t}\n}\n// ----\n// set(string,uint256,uint256): 0x60, 5, 0, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 1, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 4, 32, \"01234567890123456789012345678901\" -> 0\n// set(string,uint256,uint256): 0x60, 5, 5, 32, \"01234567890123456789012345678901\" -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter.sol b/examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter.sol new file mode 100644 index 00000000..151fe089 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter.sol @@ -0,0 +1,24 @@ +contract C { + function test(uint256 len, uint idx) public returns (uint256) + { + uint[] memory array = new uint[](len); + uint result = receiver(array, idx); + + for (uint256 i = 0; i < array.length; i++) + require(array[i] == i + 1); + + return result; + } + function receiver(uint[] memory array, uint idx) public returns (uint256) + { + for (uint256 i = 0; i < array.length; i++) + array[i] = i + 1; + + return array[idx]; + } +} +// ---- +// test(uint256,uint256): 0, 0 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256,uint256): 1, 0 -> 1 +// test(uint256,uint256): 10, 5 -> 6 +// test(uint256,uint256): 10, 50 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter_standard_input.json b/examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter_standard_input.json new file mode 100644 index 00000000..836c28f8 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_as_parameter/array_memory_as_parameter_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_create/array_memory_create.sol b/examples/test/semanticTests/array_array_memory_create/array_memory_create.sol new file mode 100644 index 00000000..91e72bc9 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_create/array_memory_create.sol @@ -0,0 +1,11 @@ +contract C { + function create(uint256 len) public returns (uint256) + { + uint[] memory array = new uint[](len); + return array.length; + } +} +// ---- +// create(uint256): 0 -> 0 +// create(uint256): 7 -> 7 +// create(uint256): 10 -> 10 diff --git a/examples/test/semanticTests/array_array_memory_create/array_memory_create_standard_input.json b/examples/test/semanticTests/array_array_memory_create/array_memory_create_standard_input.json new file mode 100644 index 00000000..2f74195e --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_create/array_memory_create_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access.sol b/examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access.sol new file mode 100644 index 00000000..d992014c --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access.sol @@ -0,0 +1,36 @@ +contract C { + function index(uint256 len) public returns (bool) + { + uint[] memory array = new uint[](len); + + for (uint256 i = 0; i < len; i++) + array[i] = i + 1; + + for (uint256 i = 0; i < len; i++) + require(array[i] == i + 1, "Unexpected value in array!"); + + return array.length == len; + } + function accessIndex(uint256 len, int256 idx) public returns (uint256) + { + uint[] memory array = new uint[](len); + + for (uint256 i = 0; i < len; i++) + array[i] = i + 1; + + return array[uint256(idx)]; + } +} +// ---- +// index(uint256): 0 -> true +// index(uint256): 10 -> true +// index(uint256): 20 -> true +// index(uint256): 0xFF -> true +// gas irOptimized: 108272 +// gas legacy: 181536 +// gas legacyOptimized: 117442 +// accessIndex(uint256,int256): 10, 1 -> 2 +// accessIndex(uint256,int256): 10, 0 -> 1 +// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex"4e487b71", 0x32 +// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex"4e487b71", 0x32 +// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access_standard_input.json b/examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access_standard_input.json new file mode 100644 index 00000000..c047b971 --- /dev/null +++ b/examples/test/semanticTests/array_array_memory_index_access/array_memory_index_access_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference.sol b/examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference.sol new file mode 100644 index 00000000..a7e5454b --- /dev/null +++ b/examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference.sol @@ -0,0 +1,23 @@ +contract C { + uint[] storageArray; + function test(uint256 v) public { + storageArray.push() = v; + } + function getLength() public view returns (uint256) { + return storageArray.length; + } + function fetch(uint256 a) public view returns (uint256) { + return storageArray[a]; + } +} +// ---- +// getLength() -> 0 +// test(uint256): 42 -> +// getLength() -> 1 +// fetch(uint256): 0 -> 42 +// fetch(uint256): 1 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256): 23 -> +// getLength() -> 2 +// fetch(uint256): 0 -> 42 +// fetch(uint256): 1 -> 23 +// fetch(uint256): 2 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference_standard_input.json b/examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference_standard_input.json new file mode 100644 index 00000000..41aa5c94 --- /dev/null +++ b/examples/test/semanticTests/array_array_push_return_reference/array_push_return_reference_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg.sol b/examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg.sol new file mode 100644 index 00000000..b143c199 --- /dev/null +++ b/examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg.sol @@ -0,0 +1,23 @@ +contract C { + uint[] storageArray; + function test(uint256 v) public { + storageArray.push(v); + } + function getLength() public view returns (uint256) { + return storageArray.length; + } + function fetch(uint256 a) public view returns (uint256) { + return storageArray[a]; + } +} +// ---- +// getLength() -> 0 +// test(uint256): 42 -> +// getLength() -> 1 +// fetch(uint256): 0 -> 42 +// fetch(uint256): 1 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256): 23 -> +// getLength() -> 2 +// fetch(uint256): 0 -> 42 +// fetch(uint256): 1 -> 23 +// fetch(uint256): 2 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg_standard_input.json b/examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg_standard_input.json new file mode 100644 index 00000000..5f43d312 --- /dev/null +++ b/examples/test/semanticTests/array_array_push_with_arg/array_push_with_arg_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access.sol b/examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access.sol new file mode 100644 index 00000000..325323c5 --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access.sol @@ -0,0 +1,53 @@ +contract C { + uint[] storageArray; + function test_indices(uint256 len) public + { + while (storageArray.length < len) + storageArray.push(); + while (storageArray.length > len) + storageArray.pop(); + for (uint i = 0; i < len; i++) + storageArray[i] = i + 1; + + for (uint i = 0; i < len; i++) + require(storageArray[i] == i + 1); + } +} +// ---- +// test_indices(uint256): 1 -> +// test_indices(uint256): 129 -> +// gas irOptimized: 3017687 +// gas legacy: 3038668 +// gas legacyOptimized: 2995964 +// test_indices(uint256): 5 -> +// gas irOptimized: 579670 +// gas legacy: 573821 +// gas legacyOptimized: 571847 +// test_indices(uint256): 10 -> +// gas irOptimized: 157953 +// gas legacy: 160122 +// gas legacyOptimized: 156996 +// test_indices(uint256): 15 -> +// gas irOptimized: 172733 +// gas legacy: 175987 +// gas legacyOptimized: 171596 +// test_indices(uint256): 0xFF -> +// gas irOptimized: 5673823 +// gas legacy: 5715762 +// gas legacyOptimized: 5632556 +// test_indices(uint256): 1000 -> +// gas irOptimized: 18173005 +// gas legacy: 18347824 +// gas legacyOptimized: 18037248 +// test_indices(uint256): 129 -> +// gas irOptimized: 4166279 +// gas legacy: 4140124 +// gas legacyOptimized: 4108272 +// test_indices(uint256): 128 -> +// gas irOptimized: 405522 +// gas legacy: 433512 +// gas legacyOptimized: 400909 +// test_indices(uint256): 1 -> +// gas irOptimized: 583437 +// gas legacy: 576726 +// gas legacyOptimized: 575542 diff --git a/examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access_standard_input.json b/examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access_standard_input.json new file mode 100644 index 00000000..2b58da2a --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_index_access/array_storage_index_access_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test.sol b/examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test.sol new file mode 100644 index 00000000..712a7cde --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test.sol @@ -0,0 +1,27 @@ +contract C { + uint[] storageArray; + function test_boundary_check(uint256 len, uint256 access) public returns (uint256) + { + while(storageArray.length < len) + storageArray.push(); + while(storageArray.length > len) + storageArray.pop(); + return storageArray[access]; + } +} +// ---- +// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex"4e487b71", 0x32 +// test_boundary_check(uint256,uint256): 10, 9 -> 0 +// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex"4e487b71", 0x32 +// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex"4e487b71", 0x32 +// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex"4e487b71", 0x32 +// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex"4e487b71", 0x32 +// gas irOptimized: 147246 +// gas legacy: 133632 +// gas legacyOptimized: 114353 +// test_boundary_check(uint256,uint256): 256, 255 -> 0 +// gas irOptimized: 149422 +// gas legacy: 135948 +// gas legacyOptimized: 116532 +// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex"4e487b71", 0x32 +// test_boundary_check(uint256,uint256): 256, 2 -> 0 diff --git a/examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test_standard_input.json b/examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test_standard_input.json new file mode 100644 index 00000000..8b20d197 --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_index_boundary_test/array_storage_index_boundary_test_standard_input.json @@ -0,0 +1,190 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test.sol b/examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test.sol new file mode 100644 index 00000000..cdd6b70f --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test.sol @@ -0,0 +1,69 @@ +contract C { + uint[] storageArray; + function test_zeroed_indices(uint256 len) public + { + while(storageArray.length < len) + storageArray.push(); + while(storageArray.length > len) + storageArray.pop(); + + for (uint i = 0; i < len; i++) + storageArray[i] = i + 1; + + if (len > 3) + { + while(storageArray.length > 0) + storageArray.pop(); + while(storageArray.length < 3) + storageArray.push(); + + for (uint i = 3; i < len; i++) + { + assembly { + mstore(0, storageArray.slot) + let pos := add(keccak256(0, 0x20), i) + + if iszero(eq(sload(pos), 0)) { + revert(0, 0) + } + } + } + + } + + while(storageArray.length > 0) + storageArray.pop(); + while(storageArray.length < len) + storageArray.push(); + + for (uint i = 0; i < len; i++) + { + require(storageArray[i] == 0); + + uint256 val = storageArray[i]; + uint256 check; + + assembly { check := iszero(val) } + + require(check == 1); + } + } +} +// ---- +// test_zeroed_indices(uint256): 1 -> +// test_zeroed_indices(uint256): 5 -> +// gas irOptimized: 133763 +// gas legacy: 131664 +// gas legacyOptimized: 129990 +// test_zeroed_indices(uint256): 10 -> +// gas irOptimized: 228556 +// gas legacy: 225215 +// gas legacyOptimized: 222351 +// test_zeroed_indices(uint256): 15 -> +// gas irOptimized: 327360 +// gas legacy: 322899 +// gas legacyOptimized: 318907 +// test_zeroed_indices(uint256): 0xFF -> +// gas irOptimized: 5180120 +// gas legacy: 5093135 +// gas legacyOptimized: 5020523 diff --git a/examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test_standard_input.json b/examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test_standard_input.json new file mode 100644 index 00000000..63af91fc --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_index_zeroed_test/array_storage_index_zeroed_test_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access.sol b/examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access.sol new file mode 100644 index 00000000..47fddc55 --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access.sol @@ -0,0 +1,22 @@ +contract C { + uint[] storageArray; + function set_get_length(uint256 len) public returns (uint256) { + while(storageArray.length < len) + storageArray.push(); + return storageArray.length; + } +} +// ---- +// set_get_length(uint256): 0 -> 0 +// set_get_length(uint256): 1 -> 1 +// set_get_length(uint256): 10 -> 10 +// set_get_length(uint256): 20 -> 20 +// set_get_length(uint256): 0xFF -> 0xFF +// gas irOptimized: 96690 +// gas legacy: 128571 +// gas legacyOptimized: 110143 +// set_get_length(uint256): 0xFFF -> 0xFFF +// gas irOptimized: 1209116 +// gas legacy: 1689548 +// gas legacyOptimized: 1393535 +// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access_standard_input.json b/examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access_standard_input.json new file mode 100644 index 00000000..761f60ae --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_length_access/array_storage_length_access_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length.sol b/examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length.sol new file mode 100644 index 00000000..ed946e19 --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length.sol @@ -0,0 +1,10 @@ +contract C { + uint[] storageArray; + function popEmpty() public { + storageArray.pop(); + } +} +// ==== +// EVMVersion: >=petersburg +// ---- +// popEmpty() -> FAILURE, hex"4e487b71", 0x31 diff --git a/examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length_standard_input.json b/examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length_standard_input.json new file mode 100644 index 00000000..edf3fc5f --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_pop_zero_length/array_storage_pop_zero_length_standard_input.json @@ -0,0 +1,208 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty.sol b/examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty.sol new file mode 100644 index 00000000..b6965f62 --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty.sol @@ -0,0 +1,25 @@ +contract C { + uint256[] storageArray; + function pushEmpty(uint256 len) public { + while(storageArray.length < len) + storageArray.push(); + + for (uint i = 0; i < len; i++) + require(storageArray[i] == 0); + } +} +// ==== +// EVMVersion: >=petersburg +// ---- +// pushEmpty(uint256): 128 +// gas irOptimized: 410745 +// gas legacy: 400519 +// gas legacyOptimized: 388804 +// pushEmpty(uint256): 256 +// gas irOptimized: 698285 +// gas legacy: 684859 +// gas legacyOptimized: 671480 +// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # +// gas irOptimized: 100000000 +// gas legacy: 100000000 +// gas legacyOptimized: 100000000 diff --git a/examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty_standard_input.json b/examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty_standard_input.json new file mode 100644 index 00000000..5aec863e --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_push_empty/array_storage_push_empty_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address.sol b/examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address.sol new file mode 100644 index 00000000..607e1ecd --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address.sol @@ -0,0 +1,33 @@ +contract C { + address[] addressArray; + function set_get_length(uint256 len) public returns (uint256) + { + while(addressArray.length < len) + addressArray.push(); + while(addressArray.length > len) + addressArray.pop(); + return addressArray.length; + } +} +// ==== +// EVMVersion: >=petersburg +// ---- +// set_get_length(uint256): 0 -> 0 +// set_get_length(uint256): 1 -> 1 +// set_get_length(uint256): 10 -> 10 +// set_get_length(uint256): 20 -> 20 +// set_get_length(uint256): 0 -> 0 +// gas irOptimized: 77628 +// gas legacy: 77730 +// gas legacyOptimized: 77162 +// set_get_length(uint256): 0xFF -> 0xFF +// gas irOptimized: 168565 +// gas legacy: 696850 +// gas legacyOptimized: 134488 +// set_get_length(uint256): 0xFFF -> 0xFFF +// gas irOptimized: 1908127 +// gas legacy: 9857362 +// gas legacyOptimized: 1393660 +// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # +// gas irOptimized: 100000000 +// gas legacyOptimized: 100000000 diff --git a/examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address_standard_input.json b/examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address_standard_input.json new file mode 100644 index 00000000..69d466dd --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_push_empty_length_address/array_storage_push_empty_length_address_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop.sol b/examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop.sol new file mode 100644 index 00000000..a4c7d34d --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop.sol @@ -0,0 +1,27 @@ +contract C { + uint[] storageArray; + function set_get_length(uint256 len) public returns (uint256) { + while(storageArray.length < len) + storageArray.push(); + while(storageArray.length > 0) + storageArray.pop(); + return storageArray.length; + } +} +// ---- +// set_get_length(uint256): 0 -> 0 +// set_get_length(uint256): 1 -> 0 +// set_get_length(uint256): 10 -> 0 +// set_get_length(uint256): 20 -> 0 +// gas irOptimized: 106222 +// gas legacy: 105722 +// gas legacyOptimized: 103508 +// set_get_length(uint256): 0xFF -> 0 +// gas irOptimized: 833586 +// gas legacy: 807764 +// gas legacyOptimized: 784467 +// set_get_length(uint256): 0xFFF -> 0 +// gas irOptimized: 13029438 +// gas legacy: 12608096 +// gas legacyOptimized: 12239199 +// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas # diff --git a/examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop_standard_input.json b/examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop_standard_input.json new file mode 100644 index 00000000..ffd6b38c --- /dev/null +++ b/examples/test/semanticTests/array_array_storage_push_pop/array_storage_push_pop_standard_input.json @@ -0,0 +1,223 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_storage_push_pop.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > 0)\n storageArray.pop();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 106222\n// gas legacy: 105722\n// gas legacyOptimized: 103508\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage.sol b/examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage.sol new file mode 100644 index 00000000..a9d08ec0 --- /dev/null +++ b/examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage.sol @@ -0,0 +1,21 @@ +contract Test { + uint24[3][] public data; + + function set(uint24[3][] memory _data) public returns (uint256) { + data = _data; + return data.length; + } + + function get() public returns (uint24[3][] memory) { + return data; + } +} +// ---- +// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 +// gas irOptimized: 185216 +// gas legacy: 211054 +// gas legacyOptimized: 206077 +// data(uint256,uint256): 0x02, 0x02 -> 0x09 +// data(uint256,uint256): 0x05, 0x01 -> 0x11 +// data(uint256,uint256): 0x06, 0x00 -> FAILURE +// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 diff --git a/examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage_standard_input.json b/examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage_standard_input.json new file mode 100644 index 00000000..fd53d85c --- /dev/null +++ b/examples/test/semanticTests/array_arrays_complex_from_and_to_storage/arrays_complex_from_and_to_storage_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout.sol b/examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout.sol new file mode 100644 index 00000000..060cafe3 --- /dev/null +++ b/examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout.sol @@ -0,0 +1,55 @@ +contract c { + bytes data; + function test_short() public returns (uint256 r) { + assembly { + sstore(data.slot, 0) + } + for (uint8 i = 0; i < 15; i++) { + data.push(bytes1(i)); + } + assembly { + r := sload(data.slot) + } + } + + function test_long() public returns (uint256 r) { + assembly { + sstore(data.slot, 0) + } + for (uint8 i = 0; i < 33; i++) { + data.push(bytes1(i)); + } + assembly { + r := sload(data.slot) + } + } + + function test_pop() public returns (uint256 r) { + assembly { + sstore(data.slot, 0) + } + for (uint8 i = 0; i < 32; i++) { + data.push(bytes1(i)); + } + data.pop(); + data.pop(); + assembly { + r := sload(data.slot) + } + } +} +// ---- +// storageEmpty -> 1 +// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710 +// gas legacy: 59838 +// gas legacyOptimized: 58606 +// storageEmpty -> 0 +// test_long() -> 67 +// gas irOptimized: 89148 +// gas legacy: 101607 +// gas legacyOptimized: 100479 +// storageEmpty -> 0 +// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020 +// gas legacy: 61930 +// gas legacyOptimized: 59404 +// storageEmpty -> 0 diff --git a/examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout_standard_input.json b/examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout_standard_input.json new file mode 100644 index 00000000..2fc51cb0 --- /dev/null +++ b/examples/test/semanticTests/array_byte_array_storage_layout/byte_array_storage_layout_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2.sol b/examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2.sol new file mode 100644 index 00000000..e83cc545 --- /dev/null +++ b/examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2.sol @@ -0,0 +1,22 @@ +// Tests transition between short and long encoding both ways +contract c { + bytes data; + + function test() public returns (uint256) { + for (uint8 i = 0; i < 33; i++) { + data.push(bytes1(i)); + } + for (uint8 i = 0; i < data.length; i++) + if (data[i] != bytes1(i)) return i; + data.pop(); + data.pop(); + for (uint8 i = 0; i < data.length; i++) + if (data[i] != bytes1(i)) return i; + return 0; + } +} +// ---- +// test() -> 0 +// gas irOptimized: 122717 +// gas legacy: 147108 +// gas legacyOptimized: 144200 diff --git a/examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2_standard_input.json b/examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2_standard_input.json new file mode 100644 index 00000000..9554ab2e --- /dev/null +++ b/examples/test/semanticTests/array_byte_array_transitional_2/byte_array_transitional_2_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_bytes_length_member/bytes_length_member.sol b/examples/test/semanticTests/array_bytes_length_member/bytes_length_member.sol new file mode 100644 index 00000000..5159538b --- /dev/null +++ b/examples/test/semanticTests/array_bytes_length_member/bytes_length_member.sol @@ -0,0 +1,19 @@ +contract c { + function set() public returns (bool) { + data = msg.data; + return true; + } + + function getLength() public returns (uint256) { + return data.length; + } + + bytes data; +} +// ---- +// getLength() -> 0 +// set(): 1, 2 -> true +// gas irOptimized: 110422 +// gas legacy: 110951 +// gas legacyOptimized: 110576 +// getLength() -> 68 diff --git a/examples/test/semanticTests/array_bytes_length_member/bytes_length_member_standard_input.json b/examples/test/semanticTests/array_bytes_length_member/bytes_length_member_standard_input.json new file mode 100644 index 00000000..54d7ebdc --- /dev/null +++ b/examples/test/semanticTests/array_bytes_length_member/bytes_length_member_standard_input.json @@ -0,0 +1,238 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_storage_push_pop.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > 0)\n storageArray.pop();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 106222\n// gas legacy: 105722\n// gas legacyOptimized: 103508\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_storage_to_memory_conversion_ints.sol": { + "content": "contract C {\n function f() public returns (uint256 x, uint256 y) {\n x = 3;\n y = 6;\n uint256[2] memory z = [x, y];\n return (z[0], z[1]);\n }\n}\n// ----\n// f() -> 3, 6\n" + }, + "memory.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function h(uint[4] memory n) public pure returns (uint) {\n return n[0] + n[1] + n[2] + n[3];\n }\n\n function i(uint[4] memory n) public view returns (uint) {\n return this.h(n) * 2;\n }\n}\n// ----\n// h(uint256[4]): 1, 2, 3, 4 -> 10\n// i(uint256[4]): 1, 2, 3, 4 -> 20\n" + }, + "constant_var_as_array_length.sol": { + "content": "contract C {\n uint256 constant LEN = 3;\n uint256[LEN] public a;\n\n constructor(uint256[LEN] memory _a) {\n a = _a;\n }\n}\n// ----\n// constructor(): 1, 2, 3 ->\n// gas irOptimized: 124991\n// gas irOptimized code: 14800\n// gas legacy: 134317\n// gas legacy code: 46200\n// gas legacyOptimized: 127166\n// gas legacyOptimized code: 23400\n// a(uint256): 0 -> 1\n// a(uint256): 1 -> 2\n// a(uint256): 2 -> 3\n" + }, + "inline_array_return.sol": { + "content": "contract C {\n uint8[] tester;\n\n function f() public returns (uint8[5] memory) {\n return ([1, 2, 3, 4, 5]);\n }\n\n function test() public returns (uint8, uint8, uint8, uint8, uint8) {\n tester = f();\n return (tester[0], tester[1], tester[2], tester[3], tester[4]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5\n" + }, + "bytes_length_member.sol": { + "content": "contract c {\n function set() public returns (bool) {\n data = msg.data;\n return true;\n }\n\n function getLength() public returns (uint256) {\n return data.length;\n }\n\n bytes data;\n}\n// ----\n// getLength() -> 0\n// set(): 1, 2 -> true\n// gas irOptimized: 110422\n// gas legacy: 110951\n// gas legacyOptimized: 110576\n// getLength() -> 68\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup.sol b/examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup.sol new file mode 100644 index 00000000..d9c55bcc --- /dev/null +++ b/examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup.sol @@ -0,0 +1,24 @@ +contract C { + bytes s = "abcdefghabcdefghabcdefghabcdefg"; + + function fromMemory(bytes memory m) public returns (bytes16) { + assembly { mstore(m, 14) } + return bytes16(m); + } + function fromCalldata(bytes calldata c) external returns (bytes16) { + return bytes16(c); + } + function fromStorage() external returns (bytes32) { + return bytes32(s); + } + function fromSlice(bytes calldata c) external returns (bytes8) { + return bytes8(c[0:6]); + } +} +// ==== +// compileViaYul: true +// ---- +// fromMemory(bytes): 0x20, 16, "abcdefghabcdefgh" -> "abcdefghabcdef\0\0" +// fromCalldata(bytes): 0x20, 15, "abcdefghabcdefgh" -> "abcdefghabcdefg\0" +// fromStorage() -> "abcdefghabcdefghabcdefghabcdefg\0" +// fromSlice(bytes): 0x20, 15, "abcdefghabcdefgh" -> "abcdef\0\0" diff --git a/examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup_standard_input.json b/examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup_standard_input.json new file mode 100644 index 00000000..317a9560 --- /dev/null +++ b/examples/test/semanticTests/array_bytes_to_fixed_bytes_cleanup/bytes_to_fixed_bytes_cleanup_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple.sol b/examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple.sol new file mode 100644 index 00000000..4300d8a6 --- /dev/null +++ b/examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple.sol @@ -0,0 +1,26 @@ +contract C { + bytes s = "abcdefghabcdefgh"; + bytes sLong = "abcdefghabcdefghabcdefghabcdefgh"; + + function fromMemory(bytes memory m) public returns (bytes16) { + return bytes16(m); + } + function fromCalldata(bytes calldata c) external returns (bytes16) { + return bytes16(c); + } + function fromStorage() external returns (bytes16) { + return bytes16(s); + } + function fromStorageLong() external returns (bytes32) { + return bytes32(sLong); + } + function fromSlice(bytes calldata c) external returns (bytes8) { + return bytes8(c[1:9]); + } +} +// ---- +// fromMemory(bytes): 0x20, 16, "abcdefghabcdefgh" -> "abcdefghabcdefgh" +// fromCalldata(bytes): 0x20, 16, "abcdefghabcdefgh" -> "abcdefghabcdefgh" +// fromStorage() -> "abcdefghabcdefgh" +// fromStorageLong() -> "abcdefghabcdefghabcdefghabcdefgh" +// fromSlice(bytes): 0x20, 16, "abcdefghabcdefgh" -> "bcdefgha" diff --git a/examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple_standard_input.json b/examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple_standard_input.json new file mode 100644 index 00000000..2a5fa291 --- /dev/null +++ b/examples/test/semanticTests/array_bytes_to_fixed_bytes_simple/bytes_to_fixed_bytes_simple_standard_input.json @@ -0,0 +1,199 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long.sol b/examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long.sol new file mode 100644 index 00000000..04bdd83f --- /dev/null +++ b/examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long.sol @@ -0,0 +1,21 @@ +contract C { + bytes s = "abcdefghabcdefghabcdefghabcdefgha"; + + function fromMemory(bytes memory m) public returns (bytes32) { + return bytes32(m); + } + function fromCalldata(bytes calldata c) external returns (bytes32) { + return bytes32(c); + } + function fromStorage() external returns (bytes32) { + return bytes32(s); + } + function fromSlice(bytes calldata c) external returns (bytes32) { + return bytes32(c[0:33]); + } +} +// ---- +// fromMemory(bytes): 0x20, 33, "abcdefghabcdefghabcdefghabcdefgh", "a" -> "abcdefghabcdefghabcdefghabcdefgh" +// fromCalldata(bytes): 0x20, 33, "abcdefghabcdefghabcdefghabcdefgh", "a" -> "abcdefghabcdefghabcdefghabcdefgh" +// fromStorage() -> "abcdefghabcdefghabcdefghabcdefgh" +// fromSlice(bytes): 0x20, 33, "abcdefghabcdefghabcdefghabcdefgh", "a" -> "abcdefghabcdefghabcdefghabcdefgh" diff --git a/examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long_standard_input.json b/examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long_standard_input.json new file mode 100644 index 00000000..2b922f43 --- /dev/null +++ b/examples/test/semanticTests/array_bytes_to_fixed_bytes_too_long/bytes_to_fixed_bytes_too_long_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array/calldata_array.sol b/examples/test/semanticTests/array_calldata_array/calldata_array.sol new file mode 100644 index 00000000..c524d06e --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array/calldata_array.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + + +contract C { + function f(uint256[2] calldata s) + external + pure + returns (uint256 a, uint256 b) + { + a = s[0]; + b = s[1]; + } +} +// ---- +// f(uint256[2]): 42, 23 -> 42, 23 diff --git a/examples/test/semanticTests/array_calldata_array/calldata_array_standard_input.json b/examples/test/semanticTests/array_calldata_array/calldata_array_standard_input.json new file mode 100644 index 00000000..a66b617e --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array/calldata_array_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function.sol b/examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function.sol new file mode 100644 index 00000000..d21c40ca --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; +contract Test { + function f(uint256[] calldata c) internal returns (uint a, uint b) { + return (c.length, c[0]); + } + + function g(uint256[] calldata c) external returns (uint a, uint b) { + return f(c); + } + + function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) { + return f(c[start: end]); + } +} +// ---- +// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1 +// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2 diff --git a/examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function_standard_input.json b/examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function_standard_input.json new file mode 100644 index 00000000..eb688f17 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_as_argument_internal_function/calldata_array_as_argument_internal_function_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol b/examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol new file mode 100644 index 00000000..dc1d1c31 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + + +contract C { + function f(uint256[][] calldata a) external returns (uint256) { + return 42; + } + + function g(uint256[][] calldata a) external returns (uint256) { + a[0]; + return 42; + } +} +// ---- +// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub # +// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding # +// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access # +// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE +// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access # +// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE diff --git a/examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json b/examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json new file mode 100644 index 00000000..727243a4 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle.sol b/examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle.sol new file mode 100644 index 00000000..93470f1d --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle.sol @@ -0,0 +1,29 @@ +pragma abicoder v2; + + +contract C { + function f(uint256[][1][] calldata a) external returns (uint256) { + return 42; + } + + function g(uint256[][1][] calldata a) external returns (uint256) { + a[0]; + return 42; + } + + function h(uint256[][1][] calldata a) external returns (uint256) { + a[0][0]; + return 42; + } +} +// ---- +// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub # +// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding # +// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access # +// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE +// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access # +// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 +// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE +// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42 +// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42 +// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE diff --git a/examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle_standard_input.json b/examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle_standard_input.json new file mode 100644 index 00000000..e9e5b62d --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_dynamic_invalid_static_middle/calldata_array_dynamic_invalid_static_middle_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct.sol b/examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct.sol new file mode 100644 index 00000000..006bf252 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256 b; + } + + function f(S[] calldata s) + external + pure + returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d) + { + l = s.length; + a = s[0].a; + b = s[0].b; + c = s[1].a; + d = s[1].b; + } +} +// ---- +// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4 diff --git a/examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct_standard_input.json b/examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct_standard_input.json new file mode 100644 index 00000000..8c65b393 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_of_struct/calldata_array_of_struct_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional.sol b/examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional.sol new file mode 100644 index 00000000..69104d38 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; +contract C { + function test(uint256[][2] calldata a) external returns (uint256) { + return a.length; + } + function test(uint256[][2] calldata a, uint256 i) external returns (uint256) { + return a[i].length; + } + function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) { + return a[i][j]; + } + function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) { + return this.test(a, i, j); + } +} +// ---- +// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2 +// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3 +// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4 +// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01 +// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01 +// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02 +// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02 +// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03 +// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03 +// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01 +// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01 +// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02 +// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02 +// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03 +// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03 +// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04 +// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04 +// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional_standard_input.json b/examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional_standard_input.json new file mode 100644 index 00000000..a9b7c358 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_two_dimensional/calldata_array_two_dimensional_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1.sol b/examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1.sol new file mode 100644 index 00000000..e96f4928 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; +contract C { + function test(uint256[][] calldata a) external returns (uint256) { + return a.length; + } + function test(uint256[][] calldata a, uint256 i) external returns (uint256) { + return a[i].length; + } + function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) { + return a[i][j]; + } + function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) { + return this.test(a, i, j); + } +} +// ---- +// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2 +// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3 +// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4 +// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01 +// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01 +// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02 +// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02 +// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03 +// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03 +// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01 +// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01 +// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02 +// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02 +// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03 +// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03 +// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04 +// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04 +// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex"4e487b71", 0x32 +// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1_standard_input.json b/examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1_standard_input.json new file mode 100644 index 00000000..f0909cc8 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_array_two_dimensional_1/calldata_array_two_dimensional_1_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol b/examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol new file mode 100644 index 00000000..d6ff4679 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol @@ -0,0 +1,10 @@ +pragma abicoder v2; +contract C { + function f(bytes[] calldata a, uint256 i) external returns (uint) { + return uint8(a[0][i]); + } +} +// ---- +// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61 +// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62 +// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json b/examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json new file mode 100644 index 00000000..ce545df1 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access.sol b/examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access.sol new file mode 100644 index 00000000..76af2214 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access.sol @@ -0,0 +1,44 @@ +contract C { + function f(uint256[] calldata x, uint256 start, uint256 end) external pure { + x[start:end]; + } + function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) { + return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]); + } +} +// ---- +// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> +// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> +// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> +// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 -> +// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access_standard_input.json b/examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access_standard_input.json new file mode 100644 index 00000000..ef32b869 --- /dev/null +++ b/examples/test/semanticTests/array_calldata_slice_access/calldata_slice_access_standard_input.json @@ -0,0 +1,220 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args.sol b/examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args.sol new file mode 100644 index 00000000..84c56211 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args.sol @@ -0,0 +1,28 @@ +contract C { + function f(bytes memory a, bytes memory b) public returns (bytes memory) { + return bytes.concat(a, b); + } +} +// ---- +// f(bytes,bytes): 0x40, 0x80, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 0x20, 37, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdef" +// +// f(bytes,bytes): +// 0x40, 0xa0, 64, "abcdabcdabcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" +// -> +// 0x20, 69, "abcdabcdabcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdef" +// f(bytes,bytes): 0x40, 0x80, 3, "abc", 3, "def" -> 0x20, 6, "abcdef" +// +// f(bytes,bytes): +// 0x40, 0xa0, 34, "abcdabcdabcdabcdabcdabcdabcdabcd", "ab", 30, "cdabcdabcdabcdabcdabcdabcdabcd" +// -> +// 0x20, 64, "abcdabcdabcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcdabcdabcd" +// +// f(bytes,bytes): +// 0x40, 0xa0, 34, "abcdabcdabcdabcdabcdabcdabcdabcd", "ab", 34, "cdabcdabcdabcdabcdabcdabcdabcdab", "cd" +// -> +// 0x20, 68, "abcdabcdabcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcdabcdabcd", "abcd" +// +// f(bytes,bytes): +// 0x40, 0x80, 3, "abc", 30, "dabcdabcdabcdabcdabcdabcdabcda" +// -> +// 0x20, 33, "abcdabcdabcdabcdabcdabcdabcdabcd", "a" diff --git a/examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args_standard_input.json new file mode 100644 index 00000000..66a3af54 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_2_args/bytes_concat_2_args_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "bytes_concat_different_types.sol": { + "content": "contract C {\n bytes s = \"bcdef\";\n\n function f(bytes memory a) public returns (bytes memory) {\n return bytes.concat(a, \"bcdef\");\n }\n function g(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, s);\n }\n function j(bytes calldata a) public returns (bytes memory) {\n bytes storage ref = s;\n return bytes.concat(a, ref, s);\n }\n function k(bytes calldata a, string memory b) public returns (bytes memory) {\n return bytes.concat(a, bytes(b));\n }\n function slice(bytes calldata a) public returns (bytes memory) {\n require(a.length > 2, \"\");\n return bytes.concat(a[:2], a[2:]);\n }\n function strParam(string calldata a) public returns (bytes memory) {\n return bytes.concat(bytes(a), \"bcdef\");\n }\n function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n bytes memory,\n bytes memory,\n bytes memory,\n bytes memory\n ) {\n return (\n bytes.concat(b1, b2),\n bytes.concat(b1, b3),\n bytes.concat(b1, \"bcdef\"),\n bytes.concat(b1, s)\n );\n }\n function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n return (\n bytes.concat(s, b1, c),\n bytes.concat(b1, c, b2)\n );\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n// \"aabbccddeeffgghh\",\n// \"abcdefghabcdefg\",\n// \"0123456789012345678901234567890\" ->\n// 0x80, 0xc0, 0x120, 0x160,\n// 31, \"aabbccddeeffgghhabcdefghabcdefg\",\n// 47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n// 21, \"aabbccddeeffgghhbcdef\",\n// 21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n// 0x40, 0x80,\n// 31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n// 0x40, 0x80,\n// 16, left(0x6263646566010000000000030000000000),\n// 17, left(0x010000000000030000000002000000000000)\n" + }, + "bytes_concat_nested.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(bytes.concat(a, b), c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "bytes_concat_3_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(a, b, c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\", 3, \"abc\" -> 0x20, 40, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefabc\"\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 3, \"abc\", 2, \"de\", 3, \"fgh\" -> 0x20, 8, \"abcdefgh\"\n" + }, + "bytes_concat_2_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b) public returns (bytes memory) {\n return bytes.concat(a, b);\n }\n}\n// ----\n// f(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\"\n// ->\n// 0x20, 69, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// f(bytes,bytes): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\"\n// ->\n// 0x20, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\"\n// ->\n// 0x20, 68, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcd\"\n//\n// f(bytes,bytes):\n// 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\"\n// ->\n// 0x20, 33, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args.sol b/examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args.sol new file mode 100644 index 00000000..d6b9e376 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args.sol @@ -0,0 +1,8 @@ +contract C { + function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) { + return bytes.concat(a, b, c); + } +} +// ---- +// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef", 3, "abc" -> 0x20, 40, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdefabc" +// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 3, "abc", 2, "de", 3, "fgh" -> 0x20, 8, "abcdefgh" diff --git a/examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args_standard_input.json new file mode 100644 index 00000000..d80b1f7e --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_3_args/bytes_concat_3_args_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "bytes_concat_different_types.sol": { + "content": "contract C {\n bytes s = \"bcdef\";\n\n function f(bytes memory a) public returns (bytes memory) {\n return bytes.concat(a, \"bcdef\");\n }\n function g(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, s);\n }\n function j(bytes calldata a) public returns (bytes memory) {\n bytes storage ref = s;\n return bytes.concat(a, ref, s);\n }\n function k(bytes calldata a, string memory b) public returns (bytes memory) {\n return bytes.concat(a, bytes(b));\n }\n function slice(bytes calldata a) public returns (bytes memory) {\n require(a.length > 2, \"\");\n return bytes.concat(a[:2], a[2:]);\n }\n function strParam(string calldata a) public returns (bytes memory) {\n return bytes.concat(bytes(a), \"bcdef\");\n }\n function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n bytes memory,\n bytes memory,\n bytes memory,\n bytes memory\n ) {\n return (\n bytes.concat(b1, b2),\n bytes.concat(b1, b3),\n bytes.concat(b1, \"bcdef\"),\n bytes.concat(b1, s)\n );\n }\n function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n return (\n bytes.concat(s, b1, c),\n bytes.concat(b1, c, b2)\n );\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n// \"aabbccddeeffgghh\",\n// \"abcdefghabcdefg\",\n// \"0123456789012345678901234567890\" ->\n// 0x80, 0xc0, 0x120, 0x160,\n// 31, \"aabbccddeeffgghhabcdefghabcdefg\",\n// 47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n// 21, \"aabbccddeeffgghhbcdef\",\n// 21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n// 0x40, 0x80,\n// 31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n// 0x40, 0x80,\n// 16, left(0x6263646566010000000000030000000000),\n// 17, left(0x010000000000030000000002000000000000)\n" + }, + "bytes_concat_nested.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(bytes.concat(a, b), c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "bytes_concat_3_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(a, b, c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\", 3, \"abc\" -> 0x20, 40, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefabc\"\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 3, \"abc\", 2, \"de\", 3, \"fgh\" -> 0x20, 8, \"abcdefgh\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument.sol b/examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument.sol new file mode 100644 index 00000000..030a959a --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument.sol @@ -0,0 +1,16 @@ +contract C { + function f(bytes memory a, bytes memory b) public returns (bytes32) { + return keccak256(bytes.concat(a, b)); + } + + function h(bytes memory a) internal returns (uint256) { + return a.length; + } + + function g(bytes memory a, bytes memory b) public returns (uint256) { + return h(bytes.concat(a, b)); + } +} +// ---- +// f(bytes,bytes): 0x40, 0x80, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 0x1106e19b6f06d1cce71c2d816754f83dfa5b95df958c5cbf12b7c472320c427c +// g(bytes,bytes): 0x40, 0x80, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 37 diff --git a/examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument_standard_input.json new file mode 100644 index 00000000..34ed09d0 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_as_argument/bytes_concat_as_argument_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "bytes_concat_different_types.sol": { + "content": "contract C {\n bytes s = \"bcdef\";\n\n function f(bytes memory a) public returns (bytes memory) {\n return bytes.concat(a, \"bcdef\");\n }\n function g(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, s);\n }\n function j(bytes calldata a) public returns (bytes memory) {\n bytes storage ref = s;\n return bytes.concat(a, ref, s);\n }\n function k(bytes calldata a, string memory b) public returns (bytes memory) {\n return bytes.concat(a, bytes(b));\n }\n function slice(bytes calldata a) public returns (bytes memory) {\n require(a.length > 2, \"\");\n return bytes.concat(a[:2], a[2:]);\n }\n function strParam(string calldata a) public returns (bytes memory) {\n return bytes.concat(bytes(a), \"bcdef\");\n }\n function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n bytes memory,\n bytes memory,\n bytes memory,\n bytes memory\n ) {\n return (\n bytes.concat(b1, b2),\n bytes.concat(b1, b3),\n bytes.concat(b1, \"bcdef\"),\n bytes.concat(b1, s)\n );\n }\n function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n return (\n bytes.concat(s, b1, c),\n bytes.concat(b1, c, b2)\n );\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n// \"aabbccddeeffgghh\",\n// \"abcdefghabcdefg\",\n// \"0123456789012345678901234567890\" ->\n// 0x80, 0xc0, 0x120, 0x160,\n// 31, \"aabbccddeeffgghhabcdefghabcdefg\",\n// 47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n// 21, \"aabbccddeeffgghhbcdef\",\n// 21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n// 0x40, 0x80,\n// 31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n// 0x40, 0x80,\n// 16, left(0x6263646566010000000000030000000000),\n// 17, left(0x010000000000030000000002000000000000)\n" + }, + "bytes_concat_nested.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(bytes.concat(a, b), c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "bytes_concat_3_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(a, b, c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\", 3, \"abc\" -> 0x20, 40, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefabc\"\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 3, \"abc\", 2, \"de\", 3, \"fgh\" -> 0x20, 8, \"abcdefgh\"\n" + }, + "bytes_concat_2_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b) public returns (bytes memory) {\n return bytes.concat(a, b);\n }\n}\n// ----\n// f(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\"\n// ->\n// 0x20, 69, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// f(bytes,bytes): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\"\n// ->\n// 0x20, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\"\n// ->\n// 0x20, 68, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcd\"\n//\n// f(bytes,bytes):\n// 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\"\n// ->\n// 0x20, 33, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"a\"\n" + }, + "bytes_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n bytes memory b = \"\";\n return bytes.concat(\n bytes.concat(b),\n bytes.concat(b, b),\n bytes.concat(\"\", b),\n bytes.concat(b, \"\")\n );\n }\n\n function g() public returns (bytes memory) {\n return bytes.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (bytes memory) {\n bytes memory b = \"\";\n return bytes.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + }, + "bytes_concat_as_argument.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b) public returns (bytes32) {\n return keccak256(bytes.concat(a, b));\n }\n\n function h(bytes memory a) internal returns (uint256) {\n return a.length;\n }\n\n function g(bytes memory a, bytes memory b) public returns (uint256) {\n return h(bytes.concat(a, b));\n }\n}\n// ----\n// f(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x1106e19b6f06d1cce71c2d816754f83dfa5b95df958c5cbf12b7c472320c427c\n// g(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 37\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types.sol b/examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types.sol new file mode 100644 index 00000000..a6b7f573 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types.sol @@ -0,0 +1,73 @@ +contract C { + bytes s = "bcdef"; + + function f(bytes memory a) public returns (bytes memory) { + return bytes.concat(a, "bcdef"); + } + function g(bytes calldata a) public returns (bytes memory) { + return bytes.concat(a, "abcdefghabcdefghabcdefghabcdefghab"); + } + function h(bytes calldata a) public returns (bytes memory) { + return bytes.concat(a, s); + } + function j(bytes calldata a) public returns (bytes memory) { + bytes storage ref = s; + return bytes.concat(a, ref, s); + } + function k(bytes calldata a, string memory b) public returns (bytes memory) { + return bytes.concat(a, bytes(b)); + } + function slice(bytes calldata a) public returns (bytes memory) { + require(a.length > 2, ""); + return bytes.concat(a[:2], a[2:]); + } + function strParam(string calldata a) public returns (bytes memory) { + return bytes.concat(bytes(a), "bcdef"); + } + function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns ( + bytes memory, + bytes memory, + bytes memory, + bytes memory + ) { + return ( + bytes.concat(b1, b2), + bytes.concat(b1, b3), + bytes.concat(b1, "bcdef"), + bytes.concat(b1, s) + ); + } + function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) { + return ( + bytes.concat(s, b1, c), + bytes.concat(b1, c, b2) + ); + } +} +// ==== +// revertStrings: debug +// ---- +// f(bytes): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 37, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdef" +// g(bytes): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 66, "abcdabcdabcdabcdabcdabcdabcdabcd", "abcdefghabcdefghabcdefghabcdefgh", "ab" +// h(bytes): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 37, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdef" +// j(bytes): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 42, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdefbcdef" +// k(bytes,string): 0x40, 0x80, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 0x20, 37, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdef" +// slice(bytes): 0x20, 4, "abcd" -> 0x20, 4, "abcd" +// strParam(string): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 37, "abcdabcdabcdabcdabcdabcdabcdabcd", "bcdef" +// fixedBytesParam(bytes16,bytes15,bytes31): +// "aabbccddeeffgghh", +// "abcdefghabcdefg", +// "0123456789012345678901234567890" -> +// 0x80, 0xc0, 0x120, 0x160, +// 31, "aabbccddeeffgghhabcdefghabcdefg", +// 47, "aabbccddeeffgghh0123456789012345", "678901234567890", +// 21, "aabbccddeeffgghhbcdef", +// 21, "aabbccddeeffgghhbcdef" +// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) -> +// 0x40, 0x80, +// 31, left(0x62636465660102030405061011121314151617181920212223242526272829), +// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C +// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) -> +// 0x40, 0x80, +// 16, left(0x6263646566010000000000030000000000), +// 17, left(0x010000000000030000000002000000000000) diff --git a/examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types_standard_input.json new file mode 100644 index 00000000..2b80675b --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_different_types/bytes_concat_different_types_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "bytes_concat_different_types.sol": { + "content": "contract C {\n bytes s = \"bcdef\";\n\n function f(bytes memory a) public returns (bytes memory) {\n return bytes.concat(a, \"bcdef\");\n }\n function g(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, s);\n }\n function j(bytes calldata a) public returns (bytes memory) {\n bytes storage ref = s;\n return bytes.concat(a, ref, s);\n }\n function k(bytes calldata a, string memory b) public returns (bytes memory) {\n return bytes.concat(a, bytes(b));\n }\n function slice(bytes calldata a) public returns (bytes memory) {\n require(a.length > 2, \"\");\n return bytes.concat(a[:2], a[2:]);\n }\n function strParam(string calldata a) public returns (bytes memory) {\n return bytes.concat(bytes(a), \"bcdef\");\n }\n function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n bytes memory,\n bytes memory,\n bytes memory,\n bytes memory\n ) {\n return (\n bytes.concat(b1, b2),\n bytes.concat(b1, b3),\n bytes.concat(b1, \"bcdef\"),\n bytes.concat(b1, s)\n );\n }\n function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n return (\n bytes.concat(s, b1, c),\n bytes.concat(b1, c, b2)\n );\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n// \"aabbccddeeffgghh\",\n// \"abcdefghabcdefg\",\n// \"0123456789012345678901234567890\" ->\n// 0x80, 0xc0, 0x120, 0x160,\n// 31, \"aabbccddeeffgghhabcdefghabcdefg\",\n// 47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n// 21, \"aabbccddeeffgghhbcdef\",\n// 21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n// 0x40, 0x80,\n// 31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n// 0x40, 0x80,\n// 16, left(0x6263646566010000000000030000000000),\n// 17, left(0x010000000000030000000002000000000000)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list.sol b/examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list.sol new file mode 100644 index 00000000..7041ff85 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (bytes memory) { + return bytes.concat(); + } +} +// ---- +// f() -> 0x20, 0 diff --git a/examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list_standard_input.json new file mode 100644 index 00000000..0a938821 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_empty_argument_list/bytes_concat_empty_argument_list_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings.sol b/examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings.sol new file mode 100644 index 00000000..10d31162 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings.sol @@ -0,0 +1,24 @@ +contract C { + function f() public returns (bytes memory) { + bytes memory b = ""; + return bytes.concat( + bytes.concat(b), + bytes.concat(b, b), + bytes.concat("", b), + bytes.concat(b, "") + ); + } + + function g() public returns (bytes memory) { + return bytes.concat("", "abc", hex"", "abc", unicode""); + } + + function h() public returns (bytes memory) { + bytes memory b = ""; + return bytes.concat(b, "abc", b, "abc", b); + } +} +// ---- +// f() -> 0x20, 0 +// g() -> 0x20, 6, "abcabc" +// h() -> 0x20, 6, "abcabc" diff --git a/examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings_standard_input.json new file mode 100644 index 00000000..a32c97a2 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_empty_strings/bytes_concat_empty_strings_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "bytes_concat_different_types.sol": { + "content": "contract C {\n bytes s = \"bcdef\";\n\n function f(bytes memory a) public returns (bytes memory) {\n return bytes.concat(a, \"bcdef\");\n }\n function g(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, s);\n }\n function j(bytes calldata a) public returns (bytes memory) {\n bytes storage ref = s;\n return bytes.concat(a, ref, s);\n }\n function k(bytes calldata a, string memory b) public returns (bytes memory) {\n return bytes.concat(a, bytes(b));\n }\n function slice(bytes calldata a) public returns (bytes memory) {\n require(a.length > 2, \"\");\n return bytes.concat(a[:2], a[2:]);\n }\n function strParam(string calldata a) public returns (bytes memory) {\n return bytes.concat(bytes(a), \"bcdef\");\n }\n function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n bytes memory,\n bytes memory,\n bytes memory,\n bytes memory\n ) {\n return (\n bytes.concat(b1, b2),\n bytes.concat(b1, b3),\n bytes.concat(b1, \"bcdef\"),\n bytes.concat(b1, s)\n );\n }\n function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n return (\n bytes.concat(s, b1, c),\n bytes.concat(b1, c, b2)\n );\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n// \"aabbccddeeffgghh\",\n// \"abcdefghabcdefg\",\n// \"0123456789012345678901234567890\" ->\n// 0x80, 0xc0, 0x120, 0x160,\n// 31, \"aabbccddeeffgghhabcdefghabcdefg\",\n// 47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n// 21, \"aabbccddeeffgghhbcdef\",\n// 21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n// 0x40, 0x80,\n// 31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n// 0x40, 0x80,\n// 16, left(0x6263646566010000000000030000000000),\n// 17, left(0x010000000000030000000002000000000000)\n" + }, + "bytes_concat_nested.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(bytes.concat(a, b), c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "bytes_concat_3_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(a, b, c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\", 3, \"abc\" -> 0x20, 40, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefabc\"\n// f(bytes,bytes,bytes): 0x60, 0xa0, 0xe0, 3, \"abc\", 2, \"de\", 3, \"fgh\" -> 0x20, 8, \"abcdefgh\"\n" + }, + "bytes_concat_2_args.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b) public returns (bytes memory) {\n return bytes.concat(a, b);\n }\n}\n// ----\n// f(bytes,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\"\n// ->\n// 0x20, 69, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// f(bytes,bytes): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\"\n// ->\n// 0x20, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\"\n//\n// f(bytes,bytes):\n// 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\"\n// ->\n// 0x20, 68, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcd\"\n//\n// f(bytes,bytes):\n// 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\"\n// ->\n// 0x20, 33, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"a\"\n" + }, + "bytes_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n bytes memory b = \"\";\n return bytes.concat(\n bytes.concat(b),\n bytes.concat(b, b),\n bytes.concat(\"\", b),\n bytes.concat(b, \"\")\n );\n }\n\n function g() public returns (bytes memory) {\n return bytes.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (bytes memory) {\n bytes memory b = \"\";\n return bytes.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested.sol b/examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested.sol new file mode 100644 index 00000000..f4190322 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) { + return bytes.concat(bytes.concat(a, b), c); + } +} +// ---- +// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, "ab" -> 0x20, 6, "ababab" diff --git a/examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested_standard_input.json b/examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested_standard_input.json new file mode 100644 index 00000000..f8e3e412 --- /dev/null +++ b/examples/test/semanticTests/array_concat_bytes_concat_nested/bytes_concat_nested_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "bytes_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (bytes memory) {\n return bytes.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "bytes_concat_different_types.sol": { + "content": "contract C {\n bytes s = \"bcdef\";\n\n function f(bytes memory a) public returns (bytes memory) {\n return bytes.concat(a, \"bcdef\");\n }\n function g(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(bytes calldata a) public returns (bytes memory) {\n return bytes.concat(a, s);\n }\n function j(bytes calldata a) public returns (bytes memory) {\n bytes storage ref = s;\n return bytes.concat(a, ref, s);\n }\n function k(bytes calldata a, string memory b) public returns (bytes memory) {\n return bytes.concat(a, bytes(b));\n }\n function slice(bytes calldata a) public returns (bytes memory) {\n require(a.length > 2, \"\");\n return bytes.concat(a[:2], a[2:]);\n }\n function strParam(string calldata a) public returns (bytes memory) {\n return bytes.concat(bytes(a), \"bcdef\");\n }\n function fixedBytesParam(bytes16 b1, bytes15 b2, bytes31 b3) public returns (\n bytes memory,\n bytes memory,\n bytes memory,\n bytes memory\n ) {\n return (\n bytes.concat(b1, b2),\n bytes.concat(b1, b3),\n bytes.concat(b1, \"bcdef\"),\n bytes.concat(b1, s)\n );\n }\n function fixedBytesParam2(bytes calldata c, bytes6 b1, bytes6 b2) public returns (bytes memory, bytes memory) {\n return (\n bytes.concat(s, b1, c),\n bytes.concat(b1, c, b2)\n );\n }\n}\n// ====\n// revertStrings: debug\n// ----\n// f(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// g(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 66, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdefghabcdefghabcdefghabcdefgh\", \"ab\"\n// h(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// j(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 42, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdefbcdef\"\n// k(bytes,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// slice(bytes): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 37, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"bcdef\"\n// fixedBytesParam(bytes16,bytes15,bytes31):\n// \"aabbccddeeffgghh\",\n// \"abcdefghabcdefg\",\n// \"0123456789012345678901234567890\" ->\n// 0x80, 0xc0, 0x120, 0x160,\n// 31, \"aabbccddeeffgghhabcdefghabcdefg\",\n// 47, \"aabbccddeeffgghh0123456789012345\", \"678901234567890\",\n// 21, \"aabbccddeeffgghhbcdef\",\n// 21, \"aabbccddeeffgghhbcdef\"\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x010203040506), left(0x0708090A0B0C), 20, left(0x1011121314151617181920212223242526272829) ->\n// 0x40, 0x80,\n// 31, left(0x62636465660102030405061011121314151617181920212223242526272829),\n// 32, 0x01020304050610111213141516171819202122232425262728290708090A0B0C\n// fixedBytesParam2(bytes,bytes6,bytes6): 0x60, left(0x01), left(0x02), 5, left(0x03) ->\n// 0x40, 0x80,\n// 16, left(0x6263646566010000000000030000000000),\n// 17, left(0x010000000000030000000002000000000000)\n" + }, + "bytes_concat_nested.sol": { + "content": "contract C {\n function f(bytes memory a, bytes memory b, bytes memory c) public returns (bytes memory) {\n return bytes.concat(bytes.concat(a, b), c);\n }\n}\n// ----\n// f(bytes,bytes,bytes): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length.sol b/examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length.sol new file mode 100644 index 00000000..342f3218 --- /dev/null +++ b/examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length.sol @@ -0,0 +1,19 @@ +contract C { + uint256 constant LEN = 3; + uint256[LEN] public a; + + constructor(uint256[LEN] memory _a) { + a = _a; + } +} +// ---- +// constructor(): 1, 2, 3 -> +// gas irOptimized: 124991 +// gas irOptimized code: 14800 +// gas legacy: 134317 +// gas legacy code: 46200 +// gas legacyOptimized: 127166 +// gas legacyOptimized code: 23400 +// a(uint256): 0 -> 1 +// a(uint256): 1 -> 2 +// a(uint256): 2 -> 3 diff --git a/examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length_standard_input.json b/examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length_standard_input.json new file mode 100644 index 00000000..631a9a1d --- /dev/null +++ b/examples/test/semanticTests/array_constant_var_as_array_length/constant_var_as_array_length_standard_input.json @@ -0,0 +1,232 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_storage_push_pop.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > 0)\n storageArray.pop();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 106222\n// gas legacy: 105722\n// gas legacyOptimized: 103508\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_storage_to_memory_conversion_ints.sol": { + "content": "contract C {\n function f() public returns (uint256 x, uint256 y) {\n x = 3;\n y = 6;\n uint256[2] memory z = [x, y];\n return (z[0], z[1]);\n }\n}\n// ----\n// f() -> 3, 6\n" + }, + "memory.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function h(uint[4] memory n) public pure returns (uint) {\n return n[0] + n[1] + n[2] + n[3];\n }\n\n function i(uint[4] memory n) public view returns (uint) {\n return this.h(n) * 2;\n }\n}\n// ----\n// h(uint256[4]): 1, 2, 3, 4 -> 10\n// i(uint256[4]): 1, 2, 3, 4 -> 20\n" + }, + "constant_var_as_array_length.sol": { + "content": "contract C {\n uint256 constant LEN = 3;\n uint256[LEN] public a;\n\n constructor(uint256[LEN] memory _a) {\n a = _a;\n }\n}\n// ----\n// constructor(): 1, 2, 3 ->\n// gas irOptimized: 124991\n// gas irOptimized code: 14800\n// gas legacy: 134317\n// gas legacy code: 46200\n// gas legacyOptimized: 127166\n// gas legacyOptimized code: 23400\n// a(uint256): 0 -> 1\n// a(uint256): 1 -> 2\n// a(uint256): 2 -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage.sol b/examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage.sol new file mode 100644 index 00000000..ecfe565f --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage.sol @@ -0,0 +1,26 @@ +contract c { + uint[9] m_data; + uint[] m_data_dyn; + uint8[][] m_byte_data; + function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) { + m_data = a; + m_data_dyn = a; + m_byte_data = b; + return b[3][1]; // note that access and declaration are reversed to each other + } + function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) { + a = m_data.length; + b = m_data[7]; + c = m_data_dyn.length; + d = m_data_dyn[7]; + e = m_byte_data.length; + f = m_byte_data[3].length; + g = m_byte_data[3][1]; + } +} +// ---- +// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 +// gas irOptimized: 647725 +// gas legacy: 694354 +// gas legacyOptimized: 693849 +// retrieve() -> 9, 28, 9, 28, 4, 3, 32 diff --git a/examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage_standard_input.json new file mode 100644 index 00000000..0ea74d11 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_calldata_storage/array_copy_calldata_storage_standard_input.json @@ -0,0 +1,202 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128.sol b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128.sol new file mode 100644 index 00000000..761feebe --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128.sol @@ -0,0 +1,26 @@ +// Test to see if cleanup is performed properly during array copying +contract C { + uint128[] x; + function f() public returns(bool) { + x.push(42); x.push(42); x.push(42); x.push(42); + uint128[] memory y = new uint128[](1); + y[0] = 23; + x = y; + assembly { sstore(x.slot, 4) } + + assert(x[0] == 23); + assert(x[1] == 0); + + assert(x[2] == 0); + // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of + // the slot dirty. + assert(x[3] == 0); + + return true; + } +} +// ---- +// f() -> true +// gas irOptimized: 92740 +// gas legacy: 93035 +// gas legacyOptimized: 92257 diff --git a/examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128_standard_input.json new file mode 100644 index 00000000..ac08644f --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint128/array_copy_cleanup_uint128_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40.sol b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40.sol new file mode 100644 index 00000000..d65f4f37 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40.sol @@ -0,0 +1,51 @@ +// Issue 9832: Test to see if cleanup is performed properly after array copying +contract C { + uint40[] x; + function f() public returns(bool) { + + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + x.push(42); x.push(42); x.push(42); x.push(42); + + uint40[] memory y = new uint40[](1); + y[0] = 23; + x = y; + + assembly { sstore(x.slot, 20) } + + assert(x[0] == 23); + assert(x[1] == 0); + assert(x[2] == 0); + assert(x[3] == 0); + + assert(x[4] == 0); + assert(x[5] == 0); + assert(x[6] == 0); + assert(x[7] == 0); + + assert(x[8] == 0); + assert(x[9] == 0); + assert(x[10] == 0); + assert(x[11] == 0); + + assert(x[12] == 0); + assert(x[13] == 0); + assert(x[14] == 0); + assert(x[15] == 0); + + assert(x[16] == 0); + assert(x[17] == 0); + assert(x[18] == 0); + assert(x[19] == 0); + + return true; + + } +} +// ---- +// f() -> true +// gas irOptimized: 122541 +// gas legacy: 124643 +// gas legacyOptimized: 122801 diff --git a/examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40_standard_input.json new file mode 100644 index 00000000..70bfa339 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_cleanup_uint40/array_copy_cleanup_uint40_standard_input.json @@ -0,0 +1,211 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage.sol b/examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage.sol new file mode 100644 index 00000000..e9f1448a --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage.sol @@ -0,0 +1,18 @@ +contract C { + uint256[] x; + function f() public returns(uint256) { + x.push(42); x.push(42); x.push(42); x.push(42); + uint256[] memory y = new uint256[](1); + y[0] = 23; + x = y; + assembly { sstore(x.slot, 4) } + assert(x[1] == 0); + assert(x[2] == 0); + return x[3]; + } +} +// ---- +// f() -> 0 +// gas irOptimized: 108229 +// gas legacy: 108216 +// gas legacyOptimized: 107625 diff --git a/examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage_standard_input.json new file mode 100644 index 00000000..83ddc3d8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_clear_storage/array_copy_clear_storage_standard_input.json @@ -0,0 +1,259 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed.sol b/examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed.sol new file mode 100644 index 00000000..13cb9c28 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed.sol @@ -0,0 +1,50 @@ +contract C { + uint128[] x; + uint64[] x1; + uint120[] x2; + function f() public returns(uint128) { + x.push(42); x.push(42); x.push(42); x.push(42); + uint128[] memory y = new uint128[](1); + y[0] = 23; + x = y; + assembly { sstore(x.slot, 4) } + assert(x[0] == 23); + assert(x[2] == 0); + assert(x[3] == 0); + return x[1]; + } + + function g() public returns(uint64) { + x1.push(42); x1.push(42); x1.push(42); x1.push(42); + uint64[] memory y = new uint64[](1); + y[0] = 23; + x1 = y; + assembly { sstore(x1.slot, 4) } + assert(x1[0] == 23); + assert(x1[2] == 0); + assert(x1[3] == 0); + return x1[1]; + } + + function h() public returns(uint120) { + x2.push(42); x2.push(42); x2.push(42); x2.push(42); + uint120[] memory y = new uint120[](1); + y[0] = 23; + x2 = y; + assembly { sstore(x2.slot, 4) } + assert(x2[0] == 23); + assert(x2[2] == 0); + assert(x2[3] == 0); + return x2[1]; + } +} +// ---- +// f() -> 0 +// gas irOptimized: 92800 +// gas legacy: 93006 +// gas legacyOptimized: 92261 +// g() -> 0 +// h() -> 0 +// gas irOptimized: 92862 +// gas legacy: 93028 +// gas legacyOptimized: 92303 diff --git a/examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed_standard_input.json new file mode 100644 index 00000000..2b10e500 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_clear_storage_packed/array_copy_clear_storage_packed_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing.sol b/examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing.sol new file mode 100644 index 00000000..ee564d01 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing.sol @@ -0,0 +1,23 @@ +contract c { + bytes8[] data1; // 4 per slot + bytes10[] data2; // 3 per slot + + function test() + public + returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e) + { + data1 = new bytes8[](9); + for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i)); + data2 = data1; + a = data2[1]; + b = data2[2]; + c = data2[3]; + d = data2[4]; + e = data2[5]; + } +} +// ---- +// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 +// gas irOptimized: 208415 +// gas legacy: 220711 +// gas legacyOptimized: 220097 diff --git a/examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing_standard_input.json new file mode 100644 index 00000000..053542ef --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_different_packing/array_copy_different_packing_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array.sol b/examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array.sol new file mode 100644 index 00000000..bb621fcc --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array.sol @@ -0,0 +1,46 @@ +contract c { + uint[3][90][] large; + uint[3][3][] small; + function test() public returns (uint r) { + for (uint i = 0; i < 7; i++) { + large.push(); + small.push(); + } + large[3][2][0] = 2; + large[1] = large[3]; + small[3][2][0] = 2; + small[1] = small[2]; + r = (( + small[3][2][0] * 0x100 | + small[1][2][0]) * 0x100 | + large[3][2][0]) * 0x100 | + large[1][2][0]; + delete small; + delete large; + + } + function clear() public returns (uint, uint) { + for (uint i = 0; i < 7; i++) { + large.push(); + small.push(); + } + small[3][2][0] = 0; + large[3][2][0] = 0; + while (small.length > 0) + small.pop(); + while (large.length > 0) + large.pop(); + return (small.length, large.length); + } +} +// ---- +// test() -> 0x02000202 +// gas irOptimized: 4549676 +// gas legacy: 4475394 +// gas legacyOptimized: 4447665 +// storageEmpty -> 1 +// clear() -> 0, 0 +// gas irOptimized: 4478184 +// gas legacy: 4407185 +// gas legacyOptimized: 4381337 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array_standard_input.json new file mode 100644 index 00000000..2820fde1 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_including_array/array_copy_including_array_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage.sol b/examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage.sol new file mode 100644 index 00000000..205920f6 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage.sol @@ -0,0 +1,28 @@ +contract C { + uint128[13] unused; + uint32[] a; + uint32[3] b; + function f() public returns (uint32, uint256) { + uint32[] memory m = new uint32[](3); + m[0] = 1; + m[1] = 2; + m[2] = 3; + a = m; + assert(a[0] == m[0]); + assert(a[1] == m[1]); + assert(a[2] == m[2]); + return (a[0], a.length); + } + function g() public returns (uint32, uint32, uint32) { + uint32[3] memory m; + m[0] = 1; m[1] = 2; m[2] = 3; + a = m; + b = m; + assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]); + assert(a.length == b.length); + return (a[0], b[1], a[2]); + } +} +// ---- +// f() -> 1, 3 +// g() -> 1, 2, 3 diff --git a/examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage_standard_input.json new file mode 100644 index 00000000..4a245668 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_memory_to_storage/array_copy_memory_to_storage_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array.sol b/examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array.sol new file mode 100644 index 00000000..2d325a80 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array.sol @@ -0,0 +1,17 @@ +contract c { + uint256[4][] a; + uint256[10][] b; + uint256[][] c; + + function test(uint256[2][] calldata d) external returns (uint256) { + a = d; + b = a; + c = b; + return c[1][1] | c[1][2] | c[1][3] | c[1][4]; + } +} +// ---- +// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 +// gas irOptimized: 689552 +// gas legacy: 686176 +// gas legacyOptimized: 685611 diff --git a/examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array_standard_input.json new file mode 100644 index 00000000..1c5da708 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_nested_array/array_copy_nested_array_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed.sol b/examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed.sol new file mode 100644 index 00000000..335afd0a --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed.sol @@ -0,0 +1,19 @@ +// NOTE: This does not really test copying from storage to ABI directly, +// because it will always copy to memory first. +contract c { + int16[] x; + + function test() public returns (int16[] memory) { + x.push(int16(-1)); + x.push(int16(-1)); + x.push(int16(8)); + x.push(int16(-16)); + x.push(int16(-2)); + x.push(int16(6)); + x.push(int16(8)); + x.push(int16(-1)); + return x; + } +} +// ---- +// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed_standard_input.json new file mode 100644 index 00000000..3a7156ef --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_abi_signed/array_copy_storage_abi_signed_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base.sol new file mode 100644 index 00000000..54639df5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base.sol @@ -0,0 +1,22 @@ +contract c { + uint64[] data1; + uint256[] data2; + + function test() public returns (uint256 x, uint256 y) { + data2.push(11); + data1.push(0); + data1.push(1); + data1.push(2); + data1.push(3); + data1.push(4); + data2 = data1; + assert(data1[0] == data2[0]); + x = data2.length; + y = data2[4]; + } +} +// ---- +// test() -> 5, 4 +// gas irOptimized: 205667 +// gas legacy: 213863 +// gas legacyOptimized: 212901 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base_standard_input.json new file mode 100644 index 00000000..88bbb3e1 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base/array_copy_storage_storage_different_base_standard_input.json @@ -0,0 +1,280 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested.sol new file mode 100644 index 00000000..ad745ff4 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested.sol @@ -0,0 +1,26 @@ +contract c { + uint48[5][2] data1; + uint120[6][3] data2; + + function test() public returns (uint256 x, uint120 y) { + data2[0][0] = 11; + data2[1][0] = 22; + data2[2][0] = 33; + + data1[0][0] = 0; + data1[0][1] = 1; + data1[0][2] = 2; + data1[0][3] = 3; + data1[0][4] = 4; + data1[1][0] = 3; + data2 = data1; + assert(data1[0][1] == data2[0][1]); + x = data2.length; + y = data2[0][4]; + } +} +// ---- +// test() -> 3, 4 +// gas irOptimized: 169669 +// gas legacy: 175415 +// gas legacyOptimized: 172533 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested_standard_input.json new file mode 100644 index 00000000..3511a7f8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_different_base_nested/array_copy_storage_storage_different_base_nested_standard_input.json @@ -0,0 +1,214 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn.sol new file mode 100644 index 00000000..a3868540 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn.sol @@ -0,0 +1,25 @@ + +contract c { + uint[] data1; + uint[] data2; + function setData1(uint length, uint index, uint value) public { + data1 = new uint[](length); + if (index < length) + data1[index] = value; + } + function copyStorageStorage() public { data2 = data1; } + function getData2(uint index) public returns (uint len, uint val) { + len = data2.length; if (index < len) val = data2[index]; + } +} +// ---- +// setData1(uint256,uint256,uint256): 10, 5, 4 -> +// copyStorageStorage() -> +// gas irOptimized: 111350 +// gas legacy: 109272 +// gas legacyOptimized: 109262 +// getData2(uint256): 5 -> 10, 4 +// setData1(uint256,uint256,uint256): 0, 0, 0 -> +// copyStorageStorage() -> +// getData2(uint256): 0 -> 0, 0 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn_standard_input.json new file mode 100644 index 00000000..ff3e9e31 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dyn_dyn/array_copy_storage_storage_dyn_dyn_standard_input.json @@ -0,0 +1,298 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + }, + "bytes_calldata_to_string_calldata.sol": { + "content": "contract C {\n function f(bytes calldata c) public returns (string calldata s) {\n return string(c);\n }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "array_copy_storage_storage_dyn_dyn.sol": { + "content": "\ncontract c {\n uint[] data1;\n uint[] data2;\n function setData1(uint length, uint index, uint value) public {\n data1 = new uint[](length);\n if (index < length)\n data1[index] = value;\n }\n function copyStorageStorage() public { data2 = data1; }\n function getData2(uint index) public returns (uint len, uint val) {\n len = data2.length; if (index < len) val = data2[index];\n }\n}\n// ----\n// setData1(uint256,uint256,uint256): 10, 5, 4 ->\n// copyStorageStorage() ->\n// gas irOptimized: 111350\n// gas legacy: 109272\n// gas legacyOptimized: 109262\n// getData2(uint256): 5 -> 10, 4\n// setData1(uint256,uint256,uint256): 0, 0, 0 ->\n// copyStorageStorage() ->\n// getData2(uint256): 0 -> 0, 0\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic.sol new file mode 100644 index 00000000..83df3aef --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic.sol @@ -0,0 +1,22 @@ +contract c { + uint256[] data1; + uint256[] data2; + + function test() public returns (uint256 x, uint256 y) { + data2.push(11); + data1.push(0); + data1.push(1); + data1.push(2); + data1.push(3); + data1.push(4); + data2 = data1; + assert(data1[0] == data2[0]); + x = data2.length; + y = data2[4]; + } +} +// ---- +// test() -> 5, 4 +// gas irOptimized: 253591 +// gas legacy: 250892 +// gas legacyOptimized: 250045 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic_standard_input.json new file mode 100644 index 00000000..d0fb313f --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_dynamic_dynamic/array_copy_storage_storage_dynamic_dynamic_standard_input.json @@ -0,0 +1,286 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic.sol new file mode 100644 index 00000000..94e57c96 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic.sol @@ -0,0 +1,16 @@ +contract c { + uint256[9] data1; + uint256[] data2; + + function test() public returns (uint256 x, uint256 y) { + data1[8] = 4; + data2 = data1; + x = data2.length; + y = data2[8]; + } +} +// ---- +// test() -> 9, 4 +// gas irOptimized: 123180 +// gas legacy: 123566 +// gas legacyOptimized: 123202 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic_standard_input.json new file mode 100644 index 00000000..dd09042e --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_dynamic/array_copy_storage_storage_static_dynamic_standard_input.json @@ -0,0 +1,304 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + }, + "bytes_calldata_to_string_calldata.sol": { + "content": "contract C {\n function f(bytes calldata c) public returns (string calldata s) {\n return string(c);\n }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "array_copy_storage_storage_dyn_dyn.sol": { + "content": "\ncontract c {\n uint[] data1;\n uint[] data2;\n function setData1(uint length, uint index, uint value) public {\n data1 = new uint[](length);\n if (index < length)\n data1[index] = value;\n }\n function copyStorageStorage() public { data2 = data1; }\n function getData2(uint index) public returns (uint len, uint val) {\n len = data2.length; if (index < len) val = data2[index];\n }\n}\n// ----\n// setData1(uint256,uint256,uint256): 10, 5, 4 ->\n// copyStorageStorage() ->\n// gas irOptimized: 111350\n// gas legacy: 109272\n// gas legacyOptimized: 109262\n// getData2(uint256): 5 -> 10, 4\n// setData1(uint256,uint256,uint256): 0, 0, 0 ->\n// copyStorageStorage() ->\n// getData2(uint256): 0 -> 0, 0\n// storageEmpty -> 1\n" + }, + "cleanup_during_multi_element_per_slot_copy.sol": { + "content": "contract C {\n uint32[] s;\n constructor()\n {\n s.push();\n s.push();\n }\n function f() external returns (uint)\n {\n (s[1], s) = (4, [0]);\n s = [0];\n s.push();\n return s[1];\n // used to return 4 via IR.\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 90065\n// gas irOptimized code: 149000\n// gas legacy: 89553\n// gas legacy code: 126200\n// gas legacyOptimized: 83556\n// gas legacyOptimized code: 98200\n// f() -> 0\n" + }, + "array_copy_storage_storage_static_dynamic.sol": { + "content": "contract c {\n uint256[9] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[8] = 4;\n data2 = data1;\n x = data2.length;\n y = data2[8];\n }\n}\n// ----\n// test() -> 9, 4\n// gas irOptimized: 123180\n// gas legacy: 123566\n// gas legacyOptimized: 123202\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple.sol new file mode 100644 index 00000000..2fccff77 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple.sol @@ -0,0 +1,15 @@ +contract C { + bytes1[2] data1; + bytes2[2] data2; + function test() public returns (bytes2, bytes2) { + uint i; + for (i = 0; i < data1.length; ++i) + data1[i] = bytes1(uint8(1 + i)); + data2 = data1; + return (data2[0], data2[1]); + } +} +// ---- +// test() -> left(0x01), left(0x02) +// gas legacy: 90001 +// gas legacyOptimized: 89085 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple_standard_input.json new file mode 100644 index 00000000..20d279e9 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_simple/array_copy_storage_storage_static_simple_standard_input.json @@ -0,0 +1,256 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static.sol new file mode 100644 index 00000000..d1f2cbde --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static.sol @@ -0,0 +1,19 @@ +contract c { + uint256[40] data1; + uint256[20] data2; + + function test() public returns (uint256 x, uint256 y) { + data1[30] = 4; + data1[2] = 7; + data1[3] = 9; + data2[3] = 8; + data1 = data2; + x = data1[3]; + y = data1[30]; // should be cleared + } +} +// ---- +// test() -> 8, 0 +// gas irOptimized: 196251 +// gas legacy: 194842 +// gas legacyOptimized: 194281 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static_standard_input.json new file mode 100644 index 00000000..9d53b5af --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_static_static/array_copy_storage_storage_static_static_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct.sol b/examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct.sol new file mode 100644 index 00000000..e638f2da --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct.sol @@ -0,0 +1,23 @@ +contract c { + struct Data { uint x; uint y; } + Data[] data1; + Data[] data2; + function test() public returns (uint x, uint y) { + while (data1.length < 9) + data1.push(); + data1[8].x = 4; + data1[8].y = 5; + data2 = data1; + x = data2[8].x; + y = data2[8].y; + while (data1.length > 0) + data1.pop(); + data2 = data1; + } +} +// ---- +// test() -> 4, 5 +// gas irOptimized: 190628 +// gas legacy: 190828 +// gas legacyOptimized: 189657 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct_standard_input.json new file mode 100644 index 00000000..db10b7f3 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_storage_struct/array_copy_storage_storage_struct_standard_input.json @@ -0,0 +1,274 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory.sol b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory.sol new file mode 100644 index 00000000..8bc6b86a --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory.sol @@ -0,0 +1,10 @@ +contract C { + uint[] a; + function f() public returns (uint, uint) { + a.push(1); a.push(0); a.push(0); + uint[] memory b = a; + return (b[0], b.length); + } +} +// ---- +// f() -> 1, 3 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory_standard_input.json new file mode 100644 index 00000000..dba9dab5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory/array_copy_storage_to_memory_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested.sol b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested.sol new file mode 100644 index 00000000..120e7288 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; +contract C { + uint[][] a; + + function f() public returns (uint[][] memory) { + a.push(); + a.push(); + a[0].push(0); + a[0].push(1); + a[1].push(2); + a[1].push(3); + uint[][] memory m = a; + return m; + } +} +// ---- +// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3 +// gas irOptimized: 161793 +// gas legacy: 162200 +// gas legacyOptimized: 159953 diff --git a/examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested_standard_input.json new file mode 100644 index 00000000..998ce211 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_storage_to_memory_nested/array_copy_storage_to_memory_nested_standard_input.json @@ -0,0 +1,277 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover.sol b/examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover.sol new file mode 100644 index 00000000..22105f64 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover.sol @@ -0,0 +1,22 @@ +contract c { + bytes1[10] data1; + bytes2[32] data2; + function test() public returns (uint check, uint res1, uint res2) { + uint i; + for (i = 0; i < data2.length; ++i) + data2[i] = 0xffff; + check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14])); + for (i = 0; i < data1.length; ++i) + data1[i] = bytes1(uint8(1 + i)); + data2 = data1; + for (i = 0; i < 16; ++i) + res1 |= uint(uint16(data2[i])) * 0x10000**i; + for (i = 0; i < 16; ++i) + res2 |= uint(uint16(data2[16 + i])) * 0x10000**i; + } +} +// ---- +// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 +// gas irOptimized: 100496 +// gas legacy: 158109 +// gas legacyOptimized: 141019 diff --git a/examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover_standard_input.json new file mode 100644 index 00000000..780cdcc2 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_leftover/array_copy_target_leftover_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2.sol b/examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2.sol new file mode 100644 index 00000000..0a2bcffc --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2.sol @@ -0,0 +1,24 @@ +// since the copy always copies whole slots, we have to make sure that the source size maxes +// out a whole slot and at the same time there are still elements left in the target at that point +contract c { + bytes8[4] data1; // fits into one slot + bytes10[6] data2; // 4 elements need two slots + + function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) { + data1[0] = bytes8(uint64(1)); + data1[1] = bytes8(uint64(2)); + data1[2] = bytes8(uint64(3)); + data1[3] = bytes8(uint64(4)); + for (uint256 i = 0; i < data2.length; ++i) + data2[i] = bytes10(uint80(0xffff00 | (1 + i))); + data2 = data1; + r1 = data2[3]; + r2 = data2[4]; + r3 = data2[5]; + } +} +// ---- +// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 +// gas irOptimized: 93858 +// gas legacy: 97451 +// gas legacyOptimized: 94200 diff --git a/examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2_standard_input.json new file mode 100644 index 00000000..1ecf0eaf --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_leftover2/array_copy_target_leftover2_standard_input.json @@ -0,0 +1,205 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple.sol b/examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple.sol new file mode 100644 index 00000000..27fb9f0c --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple.sol @@ -0,0 +1,23 @@ +contract c { + bytes8[9] data1; // 4 per slot + bytes17[10] data2; // 1 per slot, no offset counter + + function test() + public + returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e) + { + for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i)); + data2[8] = data2[9] = bytes8(uint64(2)); + data2 = data1; + a = data2[1]; + b = data2[2]; + c = data2[3]; + d = data2[4]; + e = data2[9]; + } +} +// ---- +// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 +// gas irOptimized: 273543 +// gas legacy: 282601 +// gas legacyOptimized: 281510 diff --git a/examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple_standard_input.json new file mode 100644 index 00000000..0afcbd06 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_simple/array_copy_target_simple_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2.sol b/examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2.sol new file mode 100644 index 00000000..980e414d --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2.sol @@ -0,0 +1,23 @@ +contract c { + bytes9[7] data1; // 3 per slot + bytes32[10] data2; // 1 per slot + + function test() + public + returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e) + { + for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i)); + data2[8] = data2[9] = bytes8(uint64(2)); + data2 = data1; + a = data2[1]; + b = data2[2]; + c = data2[3]; + d = data2[4]; + e = data2[9]; + } +} +// ---- +// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 +// gas irOptimized: 232995 +// gas legacy: 235694 +// gas legacyOptimized: 235193 diff --git a/examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2_standard_input.json b/examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2_standard_input.json new file mode 100644 index 00000000..359b98d6 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_copy_target_simple_2/array_copy_target_simple_2_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping.sol b/examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping.sol new file mode 100644 index 00000000..becc3d4c --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping.sol @@ -0,0 +1,60 @@ +pragma abicoder v2; + +contract C { + mapping (uint => uint8[][]) m; + + uint8[][] s; + + constructor() { + s = new uint8[][](2); + + s[0] = new uint8[](2); + s[0][0] = 10; + s[0][1] = 11; + + s[1] = new uint8[](3); + s[1][0] = 12; + s[1][1] = 13; + s[1][2] = 14; + } + + function from_storage() public returns (uint8[][] memory) { + m[0] = new uint8[][](2); + m[0][0] = s[0]; + m[0][1] = s[1]; + return m[0]; + } + + + function from_storage_ptr() public returns (uint8[][] memory) { + uint8[][] storage sPtr = s; + m[0] = new uint8[][](2); + m[0][0] = sPtr[0]; + m[0][1] = sPtr[1]; + return m[0]; + } + + + function from_memory() public returns (uint8[][] memory) { + uint8[][] memory a = s; + m[0] = new uint8[][](2); + m[0][0] = a[0]; + m[0][1] = a[1]; + return m[0]; + } + + function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) { + m[0] = new uint8[][](2); + m[0][0] = _a[0]; + m[0][1] = _a[1]; + return m[0]; + } +} +// ---- +// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// gas irOptimized: 149868 +// gas legacy: 150737 +// gas legacyOptimized: 148690 +// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping_standard_input.json b/examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping_standard_input.json new file mode 100644 index 00000000..d7b359d8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_elements_to_mapping/array_elements_to_mapping_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory.sol b/examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory.sol new file mode 100644 index 00000000..8e92d05f --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; + +contract c { + function test1(uint256[][] calldata c) external returns (uint256, uint256) { + uint256[][] memory a1 = c; + assert(a1[0][0] == c[0][0]); + assert(a1[0][1] == c[0][1]); + return (a1.length, a1[0][0] + a1[1][1]); + } + + function test2(uint256[][2] calldata c) external returns (uint256, uint256) { + uint256[][2] memory a2 = c; + assert(a2[0][0] == c[0][0]); + assert(a2[0][1] == c[0][1]); + return (a2[0].length, a2[0][0] + a2[1][1]); + } + + function test3(uint256[2][] calldata c) external returns (uint256, uint256) { + uint256[2][] memory a3 = c; + assert(a3[0][0] == c[0][0]); + assert(a3[0][1] == c[0][1]); + return (a3.length, a3[0][0] + a3[1][1]); + } + + function test4(uint256[2][2] calldata c) external returns (uint256) { + uint256[2][2] memory a4 = c; + assert(a4[0][0] == c[0][0]); + assert(a4[0][1] == c[0][1]); + return (a4[0][0] + a4[1][1]); + } +} +// ---- +// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65 +// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 +// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 +// test4(uint256[2][2]): 23, 42, 23, 42 -> 65 diff --git a/examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..f3168977 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_calldata_to_memory/array_nested_calldata_to_memory_standard_input.json @@ -0,0 +1,289 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage.sol new file mode 100644 index 00000000..5d4e5b45 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage.sol @@ -0,0 +1,47 @@ +pragma abicoder v2; + +contract c { + uint256[][] a1; + uint256[][2] a2; + uint256[2][] a3; + uint256[2][2] a4; + + function test1(uint256[][] calldata c) external returns (uint256, uint256) { + a1 = c; + assert(a1[0][0] == c[0][0]); + assert(a1[0][1] == c[0][1]); + return (a1.length, a1[0][0] + a1[1][1]); + } + + function test2(uint256[][2] calldata c) external returns (uint256, uint256) { + a2 = c; + assert(a2[0][0] == c[0][0]); + assert(a2[0][1] == c[0][1]); + return (a2[0].length, a2[0][0] + a2[1][1]); + } + + function test3(uint256[2][] calldata c) external returns (uint256, uint256) { + a3 = c; + assert(a3[0][0] == c[0][0]); + assert(a3[0][1] == c[0][1]); + return (a3.length, a3[0][0] + a3[1][1]); + } + + function test4(uint256[2][2] calldata c) external returns (uint256) { + a4 = c; + assert(a4[0][0] == c[0][0]); + assert(a4[0][1] == c[0][1]); + return (a4[0][0] + a4[1][1]); + } +} +// ==== +// compileViaYul: true +// ---- +// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65 +// gas irOptimized: 181029 +// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 +// gas irOptimized: 157604 +// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 +// gas irOptimized: 134801 +// test4(uint256[2][2]): 23, 42, 23, 42 -> 65 +// gas irOptimized: 111177 diff --git a/examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..fd58bbda --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_calldata_to_storage/array_nested_calldata_to_storage_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage.sol b/examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage.sol new file mode 100644 index 00000000..b892ec99 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage.sol @@ -0,0 +1,49 @@ +contract Test { + uint128[13] unused; + uint256[][] a; + uint256[4][] b; + uint256[2][3] c; + + function test() external returns (uint256) { + uint256[][] memory m = new uint256[][](2); + m[0] = new uint256[](3); + m[0][0] = 7; m[0][1] = 8; m[0][2] = 9; + m[1] = new uint256[](4); + m[1][1] = 7; m[1][2] = 8; m[1][3] = 9; + a = m; + return a[0][0] + a[0][1] + a[1][3]; + } + + function test1() external returns (uint256) { + uint256[2][] memory m = new uint256[2][](1); + m[0][0] = 1; m[0][1] = 2; + b = m; + return b[0][0] + b[0][1]; + } + + function test2() external returns (uint256) { + uint256[2][2] memory m; + m[0][0] = 1; m[1][1] = 2; m[0][1] = 3; + c = m; + return c[0][0] + c[1][1] + c[0][1]; + } + + function test3() external returns (uint256) { + uint256[2][3] memory m; + m[0][0] = 7; m[1][0] = 8; m[2][0] = 9; + m[0][1] = 7; m[1][1] = 8; m[2][1] = 9; + a = m; + return a[0][0] + a[1][0] + a[2][1]; + } +} +// ---- +// test() -> 24 +// gas irOptimized: 226734 +// gas legacy: 227083 +// gas legacyOptimized: 226529 +// test1() -> 3 +// test2() -> 6 +// test3() -> 24 +// gas irOptimized: 141319 +// gas legacy: 142238 +// gas legacyOptimized: 141365 diff --git a/examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage_standard_input.json new file mode 100644 index 00000000..7db68dfb --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_memory_to_storage/array_nested_memory_to_storage_standard_input.json @@ -0,0 +1,262 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory.sol b/examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory.sol new file mode 100644 index 00000000..ebaada76 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory.sol @@ -0,0 +1,44 @@ +pragma abicoder v2; + +contract C { + uint256[][] a1; + uint256[][2] a2; + uint256[2][] a3; + uint256[2][2] a4; + + constructor() { + a1 = new uint256[][](2); + a1[0] = [1, 2]; + a1[1] = [3, 4, 5]; + + a2[0] = [6, 7, 8]; + a2[1] = [9]; + + a3.push([1, 2]); + a3.push([3, 4]); + a3.push([5, 6]); + + a4 = [[10, 11], [12, 13]]; + } + + function test1() external returns (uint256[][] memory) { + return a1; + } + + function test2() external returns (uint256[][2] memory) { + return a2; + } + + function test3() external returns (uint256[2][] memory) { + return a3; + } + + function test4() external returns (uint256[2][2] memory) { + return a4; + } +} +// ---- +// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5 +// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9 +// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6 +// test4() -> 10, 11, 12, 13 diff --git a/examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory_standard_input.json new file mode 100644 index 00000000..c9d1c535 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_nested_storage_to_memory/array_nested_storage_to_memory_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic.sol b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic.sol new file mode 100644 index 00000000..ab3c172d --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic.sol @@ -0,0 +1,51 @@ +contract C { + function testFunction1() public {} + function testFunction2() public {} + function testFunction3() public {} + + + function() external [] externalArray0; + function() external [] externalArray1; + + function() internal [] internalArray0; + function() internal [] internalArray1; + + constructor() { + externalArray0 = new function() external[] (3); + externalArray1 = [ + this.testFunction1, + this.testFunction2, + this.testFunction3 + ]; + + internalArray0 = new function() internal[] (3); + internalArray1 = [ + testFunction1, + testFunction2, + testFunction3 + ]; + } + + function copyExternalStorageArrayOfFunctionType() external returns (bool) { + assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1))); + externalArray0 = externalArray1; + return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1)); + } + + function copyInternalArrayOfFunctionType() external returns (bool) { + internalArray0 = internalArray1; + assert(internalArray0.length == 3); + + return + internalArray0.length == internalArray1.length && + internalArray0[0] == internalArray1[0] && + internalArray0[1] == internalArray1[1] && + internalArray0[2] == internalArray1[2]; + } +} +// ---- +// copyExternalStorageArrayOfFunctionType() -> true +// gas irOptimized: 104566 +// gas legacy: 108554 +// gas legacyOptimized: 102405 +// copyInternalArrayOfFunctionType() -> true diff --git a/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic_standard_input.json b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic_standard_input.json new file mode 100644 index 00000000..0754381d --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic/array_of_function_external_storage_to_storage_dynamic_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol new file mode 100644 index 00000000..2bb3bcf3 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol @@ -0,0 +1,55 @@ +contract C { + function testFunction1() public {} + function testFunction2() public view {} + function testFunction3() public pure {} + + + function() external [] externalArray0; + function() external [] externalArray1; + + function() internal [] internalArray0; + function() internal [] internalArray1; + + constructor() { + externalArray0 = new function() external[] (3); + externalArray1 = [ + this.testFunction1, + this.testFunction2, + this.testFunction3 + ]; + + internalArray0 = new function() internal[] (3); + internalArray1 = [ + testFunction1, + testFunction2, + testFunction3 + ]; + } + + + function copyExternalStorageArraysOfFunctionType() external returns (bool) + { + assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1))); + externalArray0 = externalArray1; + return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1)); + } + + function copyInternalArrayOfFunctionType() external returns (bool) + { + internalArray0 = internalArray1; + assert(internalArray0.length == 3); + + return + internalArray0.length == internalArray1.length && + internalArray0[0] == internalArray1[0] && + internalArray0[1] == internalArray1[1] && + internalArray0[2] == internalArray1[2]; + } +} +// ---- +// copyExternalStorageArraysOfFunctionType() -> true +// gas irOptimized: 104238 +// gas legacy: 108295 +// gas legacyOptimized: 102162 +// copyInternalArrayOfFunctionType() -> true +// gas legacy: 104178 diff --git a/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability_standard_input.json b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability_standard_input.json new file mode 100644 index 00000000..4955d1fa --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_function_external_storage_to_storage_dynamic_different_mutability/array_of_function_external_storage_to_storage_dynamic_different_mutability_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory.sol b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory.sol new file mode 100644 index 00000000..a43a941a --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 a; + uint64 b; + uint128 c; + } + function f(S[3] calldata c) public returns (uint128, uint64, uint128) { + S[3] memory m = c; + return (m[2].a, m[1].b, m[0].c); + } + function g(S[] calldata c) public returns (uint128, uint64, uint128) { + S[] memory m = c; + return (m[2].a, m[1].b, m[0].c); + } +} +// ---- +// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 +// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 diff --git a/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..effc2231 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_memory/array_of_struct_calldata_to_memory_standard_input.json @@ -0,0 +1,196 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage.sol new file mode 100644 index 00000000..3147401c --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 a; + uint64 b; + uint128 c; + } + uint128[137] unused; + S[] s; + function f(S[] calldata c) public returns (uint128, uint64, uint128) { + s = c; + return (s[2].a, s[1].b, s[0].c); + } +} +// ==== +// compileViaYul: true +// ---- +// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 +// gas irOptimized: 120747 diff --git a/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..0e8ec08d --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_struct_calldata_to_storage/array_of_struct_calldata_to_storage_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage.sol b/examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage.sol new file mode 100644 index 00000000..5b3fe1f7 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage.sol @@ -0,0 +1,22 @@ +contract C { + struct S { + uint128 a; + uint64 b; + uint128 c; + } + uint128[137] unused; + S[] s; + function f() public returns (uint128, uint64, uint128) { + S[] memory m = new S[](3); + m[2].a = 10; + m[1].b = 11; + m[0].c = 12; + s = m; + return (s[2].a, s[1].b, s[0].c); + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 10, 11, 12 +// gas irOptimized: 118796 diff --git a/examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage_standard_input.json new file mode 100644 index 00000000..5eb072ab --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_struct_memory_to_storage/array_of_struct_memory_to_storage_standard_input.json @@ -0,0 +1,217 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory.sol b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory.sol new file mode 100644 index 00000000..482ceccc --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256[] a; + } + + function f(S[] calldata c) external returns (uint256, uint256) { + S[] memory s = c; + assert(s.length == c.length); + for (uint i = 0; i < s.length; i++) { + assert(s[i].a.length == c[i].a.length); + for (uint j = 0; j < s[i].a.length; j++) { + assert(s[i].a[j] == c[i].a[j]); + } + } + return (s[1].a.length, s[1].a[0]); + } +} +// ---- +// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 diff --git a/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..dac356bc --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_memory/array_of_structs_containing_arrays_calldata_to_memory_standard_input.json @@ -0,0 +1,253 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage.sol new file mode 100644 index 00000000..09037719 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage.sol @@ -0,0 +1,26 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256[] a; + } + + S[] s; + + function f(S[] calldata c) external returns (uint256, uint256) { + s = c; + assert(s.length == c.length); + for (uint i = 0; i < s.length; i++) { + assert(s[i].a.length == c[i].a.length); + for (uint j = 0; j < s[i].a.length; j++) { + assert(s[i].a[j] == c[i].a[j]); + } + } + return (s[1].a.length, s[1].a[0]); + } +} +// ==== +// compileViaYul: true +// ---- +// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 +// gas irOptimized: 327456 diff --git a/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..3e94e6e5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_calldata_to_storage/array_of_structs_containing_arrays_calldata_to_storage_standard_input.json @@ -0,0 +1,238 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage.sol b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage.sol new file mode 100644 index 00000000..355c268f --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage.sol @@ -0,0 +1,29 @@ +pragma abicoder v2; + +contract C { + struct S { + uint136 p; + uint128[3] b; + uint128[] c; + } + + S[] s; + + function f() external returns (uint256, uint256, uint128, uint128) { + S[] memory m = new S[](3); + m[1] = S(0, [uint128(1), 2, 3], new uint128[](3)); + m[1].c[0] = 1; + m[1].c[1] = 2; + m[1].c[2] = 3; + s = m; + assert(s.length == m.length); + assert(s[1].b[1] == m[1].b[1]); + assert(s[1].c[0] == m[1].c[0]); + return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]); + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 3, 3, 3, 1 +// gas irOptimized: 181928 diff --git a/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage_standard_input.json new file mode 100644 index 00000000..780533a9 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_of_structs_containing_arrays_memory_to_storage/array_of_structs_containing_arrays_memory_to_storage_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot.sol b/examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot.sol new file mode 100644 index 00000000..3578f0a8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot.sol @@ -0,0 +1,17 @@ +contract C { + uint8[33] a; + uint32[9] b; + uint120[3] c; + + function f() public returns (uint8, uint32, uint120) { + a[32] = 1; a[31] = 2; a[30] = 3; + b[0] = 1; b[1] = 2; b[2] = 3; + c[2] = 3; c[1] = 1; + return (a[32], b[1], c[2]); + } +} +// ---- +// f() -> 1, 2, 3 +// gas irOptimized: 131939 +// gas legacy: 134605 +// gas legacyOptimized: 131938 diff --git a/examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot_standard_input.json b/examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot_standard_input.json new file mode 100644 index 00000000..b5ba3149 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_storage_multi_items_per_slot/array_storage_multi_items_per_slot_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping.sol b/examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping.sol new file mode 100644 index 00000000..c5519e83 --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping.sol @@ -0,0 +1,44 @@ +pragma abicoder v2; + +contract C { + mapping (uint => uint8[][]) m; + + uint8[][] s; + + constructor() { + s = new uint8[][](2); + + s[0] = new uint8[](2); + s[0][0] = 10; + s[0][1] = 11; + + s[1] = new uint8[](3); + s[1][0] = 12; + s[1][1] = 13; + s[1][2] = 14; + } + + function from_storage() public returns (uint8[][] memory) { + m[0] = s; + return m[0]; + } + + function from_storage_ptr() public returns (uint8[][] memory) { + uint8[][] storage sPtr = s; + m[0] = sPtr; + return m[0]; + } + + function from_memory() public returns (uint8[][] memory) { + uint8[][] memory a = s; + m[0] = a; + return m[0]; + } +} +// ---- +// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// gas irOptimized: 147755 +// gas legacy: 148892 +// gas legacyOptimized: 146917 +// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 diff --git a/examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping_standard_input.json b/examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping_standard_input.json new file mode 100644 index 00000000..ba0a131b --- /dev/null +++ b/examples/test/semanticTests/array_copying_array_to_mapping/array_to_mapping_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage.sol b/examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage.sol new file mode 100644 index 00000000..af2983b0 --- /dev/null +++ b/examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage.sol @@ -0,0 +1,19 @@ +contract Test { + uint24[] public data; + function set(uint24[] memory _data) public returns (uint) { + data = _data; + return data.length; + } + function get() public returns (uint24[] memory) { + return data; + } +} +// ---- +// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 +// gas irOptimized: 99616 +// gas legacy: 103509 +// gas legacyOptimized: 101266 +// data(uint256): 7 -> 8 +// data(uint256): 15 -> 16 +// data(uint256): 18 -> FAILURE +// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 diff --git a/examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage_standard_input.json new file mode 100644 index 00000000..e5bcd19e --- /dev/null +++ b/examples/test/semanticTests/array_copying_arrays_from_and_to_storage/arrays_from_and_to_storage_standard_input.json @@ -0,0 +1,235 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata.sol b/examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata.sol new file mode 100644 index 00000000..88cb47a5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes calldata c) public returns (string calldata s) { + return string(c); + } +} +// ---- +// f(bytes): 0x20, 3, "abc" -> 0x20, 3, "abc" diff --git a/examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata_standard_input.json b/examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata_standard_input.json new file mode 100644 index 00000000..af9d4a8b --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_calldata_to_string_calldata/bytes_calldata_to_string_calldata_standard_input.json @@ -0,0 +1,295 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + }, + "bytes_calldata_to_string_calldata.sol": { + "content": "contract C {\n function f(bytes calldata c) public returns (string calldata s) {\n return string(c);\n }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings.sol b/examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings.sol new file mode 100644 index 00000000..90012eed --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings.sol @@ -0,0 +1,21 @@ +contract c { + function set(uint key) public returns (bool) { data[key] = msg.data; return true; } + function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; } + mapping(uint => bytes) data; +} +// ---- +// set(uint256): 1, 2 -> true +// gas irOptimized: 110550 +// gas legacy: 111310 +// gas legacyOptimized: 110741 +// set(uint256): 2, 2, 3, 4, 5 -> true +// gas irOptimized: 177501 +// gas legacy: 178312 +// gas legacyOptimized: 177716 +// storageEmpty -> 0 +// copy(uint256,uint256): 1, 2 -> true +// storageEmpty -> 0 +// copy(uint256,uint256): 99, 1 -> true +// storageEmpty -> 0 +// copy(uint256,uint256): 99, 2 -> true +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings_standard_input.json b/examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings_standard_input.json new file mode 100644 index 00000000..a518e383 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_inside_mappings/bytes_inside_mappings_standard_input.json @@ -0,0 +1,232 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage.sol b/examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage.sol new file mode 100644 index 00000000..d1202e27 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage.sol @@ -0,0 +1,10 @@ +contract C { + bytes s; + function f() external returns (bytes1) { + bytes memory data = "abcd"; + s = data; + return s[0]; + } +} +// ---- +// f() -> "a" diff --git a/examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage_standard_input.json new file mode 100644 index 00000000..56aee0b2 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_memory_to_storage/bytes_memory_to_storage_standard_input.json @@ -0,0 +1,190 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory.sol b/examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory.sol new file mode 100644 index 00000000..84e11c13 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory.sol @@ -0,0 +1,9 @@ +contract C { + bytes s = "abcd"; + function f() external returns (bytes1) { + bytes memory data = s; + return data[0]; + } +} +// ---- +// f() -> "a" diff --git a/examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory_standard_input.json new file mode 100644 index 00000000..7f0e691c --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_storage_to_memory/bytes_storage_to_memory_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage.sol b/examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage.sol new file mode 100644 index 00000000..fe758fe8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage.sol @@ -0,0 +1,41 @@ +contract c { + bytes a; + bytes b; + function f(uint len) public returns (bytes memory) { + bytes memory x = new bytes(len); + for (uint i = 0; i < len; i++) + x[i] = bytes1(uint8(i)); + a = x; + for (uint i = 0; i < len; i++) + assert(a[i] == x[i]); + b = a; + for (uint i = 0; i < len; i++) + assert(b[i] == x[i]); + return b; + } +} +// ---- +// f(uint256): 0 -> 0x20, 0x00 +// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 +// gas irOptimized: 103268 +// gas legacy: 112904 +// gas legacyOptimized: 112647 +// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 +// gas irOptimized: 117825 +// gas legacy: 128964 +// gas legacyOptimized: 128854 +// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 +// gas irOptimized: 124091 +// gas legacy: 136092 +// gas legacyOptimized: 135469 +// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 +// gas irOptimized: 127151 +// gas legacy: 148692 +// gas legacyOptimized: 148699 +// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 +// gas legacy: 59345 +// gas legacyOptimized: 57279 +// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// gas irOptimized: 416918 +// gas legacy: 458997 +// gas legacyOptimized: 460664 diff --git a/examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage_standard_input.json new file mode 100644 index 00000000..960784e3 --- /dev/null +++ b/examples/test/semanticTests/array_copying_bytes_storage_to_storage/bytes_storage_to_storage_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element.sol b/examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element.sol new file mode 100644 index 00000000..e78d5bdd --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element.sol @@ -0,0 +1,37 @@ +// Example from https://github.com/ethereum/solidity/issues/12558 +pragma abicoder v2; +contract C { + function f(uint[] calldata a) external returns (uint[][] memory) { + uint[][] memory m = new uint[][](2); + m[0] = a; + + return m; + } +} +contract Test { + C immutable c = new C(); + + function test() external returns (bool) { + uint[] memory arr = new uint[](4); + + arr[0] = 13; + arr[1] = 14; + arr[2] = 15; + arr[3] = 16; + + uint[][] memory ret = c.f(arr); + assert(ret.length == 2); + assert(ret[0].length == 4); + assert(ret[0][0] == 13); + assert(ret[0][1] == 14); + assert(ret[0][2] == 15); + assert(ret[0][3] == 16); + assert(ret[1].length == 0); + + return true; + } +} +// ==== +// EVMVersion: >homestead +// ---- +// test() -> true diff --git a/examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element_standard_input.json b/examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element_standard_input.json new file mode 100644 index 00000000..6df1d7e5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_1d_array_into_2d_memory_array_element/calldata_1d_array_into_2d_memory_array_element_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory.sol new file mode 100644 index 00000000..192ece49 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory.sol @@ -0,0 +1,12 @@ +pragma abicoder v2; + +contract C { + function g(bytes[2] memory m) internal returns (bytes memory) { + return m[0]; + } + function f(bytes[2] calldata c) external returns (bytes memory) { + return g(c); + } +} +// ---- +// f(bytes[2]): 0x20, 0x40, 0x40, 2, "ab" -> 0x20, 2, "ab" diff --git a/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory_standard_input.json new file mode 100644 index 00000000..d9455721 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory/calldata_2d_bytes_to_memory_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2.sol b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2.sol new file mode 100644 index 00000000..3bdda304 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + function g(bytes[2] memory m) internal { + assert(m[0].length > 1); + assert(m[1].length > 1); + assert(m[0][0] == m[1][0]); + assert(m[0][1] == m[1][1]); + } + function f(bytes[2] calldata c) external { + g(c); + } +} +// ---- +// f(bytes[2]): 0x20, 0x40, 0x40, 2, "ab" -> +// f(bytes[2]): 0x20, 0x40, 0x40, 1, "a" -> FAILURE, hex"4e487b71", 0x01 diff --git a/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2_standard_input.json b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2_standard_input.json new file mode 100644 index 00000000..f8a3360e --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_2d_bytes_to_memory_2/calldata_2d_bytes_to_memory_2_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage.sol b/examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage.sol new file mode 100644 index 00000000..3df22c72 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + +contract C { + uint256[] s; + function f(uint256[] calldata data) external returns (uint) { + s = data; + return s[0]; + } +} +// ---- +// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 +// gas irOptimized: 111084 +// gas legacy: 111548 +// gas legacyOptimized: 111321 diff --git a/examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage_standard_input.json new file mode 100644 index 00000000..dc5e725a --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_dynamic_to_storage/calldata_array_dynamic_to_storage_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory.sol new file mode 100644 index 00000000..fcf4aca2 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256 b; + } + + function f(S[] calldata s) + external + pure + returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d) + { + S[] memory m = s; + l = m.length; + a = m[0].a; + b = m[0].b; + c = m[1].a; + d = m[1].b; + } +} +// ---- +// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4 diff --git a/examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory_standard_input.json new file mode 100644 index 00000000..7ae1c90c --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_of_struct_to_memory/calldata_array_of_struct_to_memory_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory.sol new file mode 100644 index 00000000..ace6550b --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint256[2] calldata c) public returns (uint256, uint256) { + uint256[2] memory m1 = c; + return (m1[0], m1[1]); + } +} +// ---- +// f(uint256[2]): 43, 57 -> 43, 57 diff --git a/examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory_standard_input.json new file mode 100644 index 00000000..5195680d --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_static_to_memory/calldata_array_static_to_memory_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping.sol b/examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping.sol new file mode 100644 index 00000000..48460586 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; + +contract C { + mapping (uint => uint8[][]) m; + + uint8[][] s; + + function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) { + m[0] = _a; + return m[0]; + } +} +// ==== +// compileViaYul: true +// ---- +// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 +// gas irOptimized: 139587 diff --git a/examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping_standard_input.json b/examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping_standard_input.json new file mode 100644 index 00000000..18aa581d --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_array_to_mapping/calldata_array_to_mapping_standard_input.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory.sol new file mode 100644 index 00000000..56be3725 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + + +contract C { + function f(bytes[] calldata a) + external + returns (uint256, uint256, bytes memory) + { + bytes memory m = a[0]; + return (a.length, m.length, m); + } +} +// ---- +// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 0x1, 0x2, 0x60, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" +// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878" -> 0x1, 0x20, 0x60, 0x20, hex"7878787878787878787878787878787878787878787878787878787878787878" +// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"7800000000000000000000000000000000000000000000000000000000000061" -> 0x1, 0x20, 0x60, 0x20, hex"7800000000000000000000000000000000000000000000000000000000000061" +// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"6100000000000000000000000000000000000000000000000000000000000078" -> 0x1, 0x20, 0x60, 0x20, hex"6100000000000000000000000000000000000000000000000000000000000078" +// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78" -> 0x1, 0x20, 0x60, 0x20, hex"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78" diff --git a/examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory_standard_input.json new file mode 100644 index 00000000..8bb29b49 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_bytes_array_to_memory/calldata_bytes_array_to_memory_standard_input.json @@ -0,0 +1,247 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage.sol b/examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage.sol new file mode 100644 index 00000000..2409893e --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage.sol @@ -0,0 +1,9 @@ +contract C { + bytes s; + function f(bytes calldata data) external returns (bytes1) { + s = data; + return s[0]; + } +} +// ---- +// f(bytes): 0x20, 0x08, "abcdefgh" -> "a" diff --git a/examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage_standard_input.json new file mode 100644 index 00000000..98d336e3 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_bytes_to_storage/calldata_bytes_to_storage_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory.sol new file mode 100644 index 00000000..ff7e9f48 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory.sol @@ -0,0 +1,9 @@ +pragma abicoder v2; + +contract C { + function f(bytes[] calldata c) external returns (bytes[] memory) { + return c; + } +} +// ---- +// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, "ab" -> 0x20, 2, 0x40, 0x80, 2, "ab", 2, "ab" diff --git a/examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory_standard_input.json new file mode 100644 index 00000000..20aec45c --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_dyn_2d_bytes_to_memory/calldata_dyn_2d_bytes_to_memory_standard_input.json @@ -0,0 +1,229 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol new file mode 100644 index 00000000..db6625c8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + + +contract C { + function f(uint256[][] calldata a) + external + returns (uint256, uint256[] memory) + { + uint256[] memory m = a[0]; + return (a.length, m); + } +} +// ---- +// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a diff --git a/examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json new file mode 100644 index 00000000..3c5fd67e --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_dynamic_array_to_memory/calldata_dynamic_array_to_memory_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory.sol b/examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory.sol new file mode 100644 index 00000000..a26936c9 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory.sol @@ -0,0 +1,12 @@ +pragma abicoder v2; + +contract Test { + struct shouldBug { + uint256[][2] deadly; + } + function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) { + return shouldBug(weapon); + } +} +// ---- +// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2 diff --git a/examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory_standard_input.json new file mode 100644 index 00000000..9c0f5010 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_nested_array_copy_to_memory/calldata_nested_array_copy_to_memory_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base.sol b/examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base.sol new file mode 100644 index 00000000..2fc3b0a0 --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; + +contract C { + bytes10[] s; + function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) { + s = c; + return (s.length, s[0], s[1], s[2]); + } +} +// ---- +// f(bytes8[]): 0x20, 3, "abcd", "bcde", "cdef" -> 3, "abcd", "bcde", "cdef" diff --git a/examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base_standard_input.json b/examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base_standard_input.json new file mode 100644 index 00000000..54bf521d --- /dev/null +++ b/examples/test/semanticTests/array_copying_calldata_to_storage_different_base/calldata_to_storage_different_base_standard_input.json @@ -0,0 +1,220 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy.sol b/examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy.sol new file mode 100644 index 00000000..e6284072 --- /dev/null +++ b/examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy.sol @@ -0,0 +1,25 @@ +contract C { + uint32[] s; + constructor() + { + s.push(); + s.push(); + } + function f() external returns (uint) + { + (s[1], s) = (4, [0]); + s = [0]; + s.push(); + return s[1]; + // used to return 4 via IR. + } +} +// ---- +// constructor() +// gas irOptimized: 90065 +// gas irOptimized code: 149000 +// gas legacy: 89553 +// gas legacy code: 126200 +// gas legacyOptimized: 83556 +// gas legacyOptimized code: 98200 +// f() -> 0 diff --git a/examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy_standard_input.json b/examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy_standard_input.json new file mode 100644 index 00000000..c832492d --- /dev/null +++ b/examples/test/semanticTests/array_copying_cleanup_during_multi_element_per_slot_copy/cleanup_during_multi_element_per_slot_copy_standard_input.json @@ -0,0 +1,301 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + }, + "bytes_calldata_to_string_calldata.sol": { + "content": "contract C {\n function f(bytes calldata c) public returns (string calldata s) {\n return string(c);\n }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "array_copy_storage_storage_dyn_dyn.sol": { + "content": "\ncontract c {\n uint[] data1;\n uint[] data2;\n function setData1(uint length, uint index, uint value) public {\n data1 = new uint[](length);\n if (index < length)\n data1[index] = value;\n }\n function copyStorageStorage() public { data2 = data1; }\n function getData2(uint index) public returns (uint len, uint val) {\n len = data2.length; if (index < len) val = data2[index];\n }\n}\n// ----\n// setData1(uint256,uint256,uint256): 10, 5, 4 ->\n// copyStorageStorage() ->\n// gas irOptimized: 111350\n// gas legacy: 109272\n// gas legacyOptimized: 109262\n// getData2(uint256): 5 -> 10, 4\n// setData1(uint256,uint256,uint256): 0, 0, 0 ->\n// copyStorageStorage() ->\n// getData2(uint256): 0 -> 0, 0\n// storageEmpty -> 1\n" + }, + "cleanup_during_multi_element_per_slot_copy.sol": { + "content": "contract C {\n uint32[] s;\n constructor()\n {\n s.push();\n s.push();\n }\n function f() external returns (uint)\n {\n (s[1], s) = (4, [0]);\n s = [0];\n s.push();\n return s[1];\n // used to return 4 via IR.\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 90065\n// gas irOptimized code: 149000\n// gas legacy: 89553\n// gas legacy code: 126200\n// gas legacyOptimized: 83556\n// gas legacyOptimized code: 98200\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage.sol b/examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage.sol new file mode 100644 index 00000000..787973c5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage.sol @@ -0,0 +1,46 @@ +pragma abicoder v2; +struct S { + uint16 x; + bytes a; + uint16 y; + bytes b; +} +contract C { + uint padding; + S data; + + function f() public returns (bytes memory, bytes memory) { + S memory x; + x.x = 7; + x.b = "1234567890123456789012345678901 1234567890123456789012345678901 123456789"; + x.a = "abcdef"; + x.y = 9; + data = x; + return (data.a, data.b); + } + function g() public returns (bytes memory, bytes memory) { + S memory x; + x.x = 7; + x.b = "12345678923456789"; + x.a = "1234567890123456789012345678901 1234567890123456789012345678901 123456789"; + x.y = 9; + data = x; + return (data.a, data.b); + } + function h() public returns (bytes memory, bytes memory) { + S memory x; + data = x; + return (data.a, data.b); + } +} +// ---- +// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 +// gas irOptimized: 179405 +// gas legacy: 180675 +// gas legacyOptimized: 179686 +// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 +// gas irOptimized: 106338 +// gas legacy: 109415 +// gas legacyOptimized: 106600 +// h() -> 0x40, 0x60, 0x00, 0x00 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage_standard_input.json new file mode 100644 index 00000000..cacd6a49 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_byte_array_in_struct_to_storage/copy_byte_array_in_struct_to_storage_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage.sol b/examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage.sol new file mode 100644 index 00000000..fc274bf4 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage.sol @@ -0,0 +1,51 @@ +function dataslot() pure returns (bytes32) { + return keccak256(abi.encode(1)); +} + +function readDataSlot(uint offset) view returns (bytes32 r) { + bytes32 s = dataslot(); + assembly { r := sload(add(s, offset)) } +} + +function readDataSlot() view returns (bytes32) { + return readDataSlot(0); +} + +function readHead() view returns (bytes32 r) { + assembly { r := sload(1) } +} + +contract C { + uint padding; + bytes data; + + function f() public returns (uint) { + bytes32 zero; + if (!(readDataSlot() == zero)) return 1; + data = "abc"; + if (!(readDataSlot() == zero)) return 2; + data = "1234567890123456789012345678901234567890123456789012345678901234567890"; + if (!(readDataSlot() != zero)) return 3; + if (!(readDataSlot(1) != zero)) return 4; + if (!(readDataSlot(2) != zero)) return 5; + if (!(readDataSlot(3) == zero)) return 6; + if (!(readDataSlot(4) == zero)) return 7; + data = "abc"; + if (!(readDataSlot() == zero)) return 8; + if (!(readDataSlot(1) == zero)) return 9; + if (!(readDataSlot(2) == zero)) return 10; + if (!(readDataSlot(3) == zero)) return 11; + data = "1234567890123456789012345678901234567890123456789012345678901234567890"; + data = "123456789012345678901234567890123456"; + if (!(readDataSlot() != zero)) return 12; + if (!(readDataSlot(1) != zero)) return 13; + if (!(readDataSlot(2) == zero)) return 14; + if (!(readDataSlot(3) == zero)) return 15; + return 0xff; + } +} +// ---- +// f() -> 0xff +// gas irOptimized: 143857 +// gas legacy: 153404 +// gas legacyOptimized: 146676 diff --git a/examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage_standard_input.json new file mode 100644 index 00000000..8e384352 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_byte_array_to_storage/copy_byte_array_to_storage_standard_input.json @@ -0,0 +1,208 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array.sol b/examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array.sol new file mode 100644 index 00000000..7db82f89 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array.sol @@ -0,0 +1,20 @@ +contract C { + function() internal returns (uint)[] x; + function() internal returns (uint)[] y; + + function test() public returns (uint256) { + x = new function() internal returns (uint)[](10); + x[9] = a; + y = x; + return y[9](); + } + + function a() public returns (uint256) { + return 7; + } +} +// ---- +// test() -> 7 +// gas irOptimized: 122459 +// gas legacy: 205176 +// gas legacyOptimized: 204971 diff --git a/examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array_standard_input.json b/examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array_standard_input.json new file mode 100644 index 00000000..d571d8b1 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_function_internal_storage_array/copy_function_internal_storage_array_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage.sol b/examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage.sol new file mode 100644 index 00000000..95ba9d8e --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage.sol @@ -0,0 +1,23 @@ +contract C { + function() internal returns (uint)[20] x; + int256 mutex; + + function one() public returns (uint256) { + function() internal returns (uint)[20] memory xmem; + x = xmem; + return 3; + } + + function two() public returns (uint256) { + if (mutex > 0) return 7; + mutex = 1; + // If this test fails, it might re-execute this function. + x[0](); + return 2; + } +} +// ---- +// one() -> 3 +// gas legacy: 140253 +// gas legacyOptimized: 140093 +// two() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage_standard_input.json new file mode 100644 index 00000000..a2d50a51 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_internal_function_array_to_storage/copy_internal_function_array_to_storage_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data.sol b/examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data.sol new file mode 100644 index 00000000..46216e91 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data.sol @@ -0,0 +1,15 @@ + +contract c { + function set() public returns (bool) { data1 = msg.data; return true; } + function reset() public returns (bool) { data1 = data2; return true; } + bytes data1; + bytes data2; +} +// ---- +// set(): 1, 2, 3, 4, 5 -> true +// gas irOptimized: 177344 +// gas legacy: 177953 +// gas legacyOptimized: 177550 +// storageEmpty -> 0 +// reset() -> true +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data_standard_input.json b/examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data_standard_input.json new file mode 100644 index 00000000..44b2727f --- /dev/null +++ b/examples/test/semanticTests/array_copying_copy_removes_bytes_data/copy_removes_bytes_data_standard_input.json @@ -0,0 +1,271 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign.sol b/examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign.sol new file mode 100644 index 00000000..ce4344e8 --- /dev/null +++ b/examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign.sol @@ -0,0 +1,30 @@ +contract receiver { + uint public received; + function recv(uint x) public { received += x + 1; } + fallback() external { received = 0x80; } +} +contract sender { + constructor() { rec = new receiver(); } + fallback() external { savedData1 = savedData2 = msg.data; } + function forward(bool selector) public returns (bool) { + if (selector) { address(rec).call(savedData1); delete savedData1; } + else { address(rec).call(savedData2); delete savedData2; } + return true; + } + function val() public returns (uint) { return rec.received(); } + receiver rec; + bytes savedData1; + bytes savedData2; +} +// ---- +// (): 7 -> +// gas irOptimized: 110822 +// gas legacy: 111388 +// gas legacyOptimized: 111065 +// val() -> 0 +// forward(bool): true -> true +// val() -> 0x80 +// forward(bool): false -> true +// val() -> 0x80 +// forward(bool): true -> true +// val() -> 0x80 diff --git a/examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign_standard_input.json b/examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign_standard_input.json new file mode 100644 index 00000000..a6c682bd --- /dev/null +++ b/examples/test/semanticTests/array_copying_copying_bytes_multiassign/copying_bytes_multiassign_standard_input.json @@ -0,0 +1,199 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy.sol b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy.sol new file mode 100644 index 00000000..ca154eee --- /dev/null +++ b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy.sol @@ -0,0 +1,19 @@ +contract C { + bytes x; + function f() public returns (uint r) { + bytes memory m = "tmp"; + assembly { + mstore(m, 8) + mstore(add(m, 32), "deadbeef15dead") + } + // via yul disabled because this truncates the string. + x = m; + assembly { + r := sload(x.slot) + } + } +} +// ==== +// compileViaYul: false +// ---- +// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010 diff --git a/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy_standard_input.json b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy_standard_input.json new file mode 100644 index 00000000..c114dc1a --- /dev/null +++ b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy/dirty_memory_bytes_to_storage_copy_standard_input.json @@ -0,0 +1,268 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir.sol b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir.sol new file mode 100644 index 00000000..3704e368 --- /dev/null +++ b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir.sol @@ -0,0 +1,18 @@ +contract C { + bytes x; + function f() public returns (uint r) { + bytes memory m = "tmp"; + assembly { + mstore(m, 8) + mstore(add(m, 32), "deadbeef15dead") + } + x = m; + assembly { + r := sload(x.slot) + } + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010 diff --git a/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir_standard_input.json b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir_standard_input.json new file mode 100644 index 00000000..eb68e70d --- /dev/null +++ b/examples/test/semanticTests/array_copying_dirty_memory_bytes_to_storage_copy_ir/dirty_memory_bytes_to_storage_copy_ir_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage.sol new file mode 100644 index 00000000..672e7435 --- /dev/null +++ b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage.sol @@ -0,0 +1,38 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][][] s1; + S[][1][] s2; + S[1][][1] s3; + + function test1(S[][][] calldata _a) public returns (S[][] memory){ + s1.push(); + s1[0] = _a[0]; + return s1[0]; + } + + function test2(S[][1][] calldata _a) public returns (S[][1] memory) { + s2.push(); + s2[0] = _a[0]; + return s2[0]; + } + + function test3(S[1][][2] calldata _a) public returns (S[1][] memory) { + s3[0] = _a[1]; + return s3[0]; + } +} +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 327921 +// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 141162 +// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 188442 diff --git a/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..a6593ddf --- /dev/null +++ b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_calldata_to_storage/elements_of_nested_array_of_structs_calldata_to_storage_standard_input.json @@ -0,0 +1,283 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage.sol b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage.sol new file mode 100644 index 00000000..f232d8ab --- /dev/null +++ b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage.sol @@ -0,0 +1,38 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][][] s1; + S[][1][] s2; + S[1][][1] s3; + + function test1(S[][][] memory _a) public returns (S[][] memory){ + s1.push(); + s1[0] = _a[0]; + return s1[0]; + } + + function test2(S[][1][] memory _a) public returns (S[][1] memory) { + s2.push(); + s2[0] = _a[0]; + return s2[0]; + } + + function test3(S[1][][2] memory _a) public returns (S[1][] memory) { + s3[0] = _a[1]; + return s3[0]; + } +} +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 332567 +// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 145409 +// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 192248 diff --git a/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage_standard_input.json new file mode 100644 index 00000000..fc55eeea --- /dev/null +++ b/examples/test/semanticTests/array_copying_elements_of_nested_array_of_structs_memory_to_storage/elements_of_nested_array_of_structs_memory_to_storage_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy.sol b/examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy.sol new file mode 100644 index 00000000..45ef42d4 --- /dev/null +++ b/examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy.sol @@ -0,0 +1,28 @@ +contract C { + bytes data; + bytes otherData; + function fromMemory() public returns (bytes1) { + bytes memory t; + uint[2] memory x; + x[0] = type(uint).max; + data = t; + data.push(); + return data[0]; + } + function fromCalldata(bytes calldata x) public returns (bytes1) { + data = x; + data.push(); + return data[0]; + } + function fromStorage() public returns (bytes1) { + // zero-length but dirty higher order bits + assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) } + data = otherData; + data.push(); + return data[0]; + } +} +// ---- +// fromMemory() -> 0x00 +// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// fromStorage() -> 0x00 diff --git a/examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy_standard_input.json b/examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy_standard_input.json new file mode 100644 index 00000000..0fd58233 --- /dev/null +++ b/examples/test/semanticTests/array_copying_empty_bytes_copy/empty_bytes_copy_standard_input.json @@ -0,0 +1,223 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage.sol b/examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage.sol new file mode 100644 index 00000000..640046a1 --- /dev/null +++ b/examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage.sol @@ -0,0 +1,56 @@ +contract C { + string log; + function() external[] fs; + function() external[] gs; + + function a() external { + log = string.concat(log, "[a called]"); + } + function b() external { + log = string.concat(log, "[b called]"); + } + + function f(function() external[] calldata x) external { + fs = x; + } + function g(function() external[] memory x) public { + fs = x; + } + function test() external returns (string memory) { + log = ""; + function() external[] memory x = new function() external[](2); + x[0] = this.a; + x[1] = this.b; + this.f(x); + fs[0](); + fs[1](); + return log; + } + function test2() external returns (string memory) { + log = ""; + function() external[] memory x = new function() external[](2); + x[0] = this.b; + x[1] = this.a; + g(x); + fs[0](); + fs[1](); + return log; + } + function test3() external returns (string memory) { + log = ""; + gs = fs; + gs[0](); + gs[1](); + return log; + } +} +// ---- +// test() -> 0x20, 0x14, "[a called][b called]" +// gas irOptimized: 116518 +// gas legacy: 118841 +// gas legacyOptimized: 116843 +// test2() -> 0x20, 0x14, "[b called][a called]" +// test3() -> 0x20, 0x14, "[b called][a called]" +// gas irOptimized: 103144 +// gas legacy: 102654 +// gas legacyOptimized: 101556 diff --git a/examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage_standard_input.json new file mode 100644 index 00000000..e2e9f091 --- /dev/null +++ b/examples/test/semanticTests/array_copying_function_type_array_to_storage/function_type_array_to_storage_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage.sol b/examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage.sol new file mode 100644 index 00000000..8a4d870b --- /dev/null +++ b/examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + +contract C { + bytes[] s; + function f() external returns (uint256) { + bytes[] memory m = new bytes[](3); + m[0] = "ab"; m[1] = "cde"; m[2] = "fghij"; + s = m; + assert(s.length == m.length); + for (uint i = 0; i < s.length; ++i) { + assert(s[i].length == m[i].length); + for (uint j = 0; j < s[i].length; ++j) { + assert(s[i][j] == m[i][j]); + } + } + return s.length; + } +} +// ---- +// f() -> 3 +// gas irOptimized: 128296 +// gas legacy: 129077 +// gas legacyOptimized: 128210 diff --git a/examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage_standard_input.json new file mode 100644 index 00000000..2727c9c5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_memory_dyn_2d_bytes_to_storage/memory_dyn_2d_bytes_to_storage_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base.sol b/examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base.sol new file mode 100644 index 00000000..af54de1b --- /dev/null +++ b/examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + +contract C { + bytes10[] s; + function f() external returns (uint256, bytes10, bytes10, bytes10) { + bytes4[] memory m = new bytes4[](3); + m[0] = "abcd"; + m[1] = "bcde"; + m[2] = "cdef"; + s = m; + return (s.length, s[0], s[1], s[2]); + } +} +// ---- +// f() -> 3, "abcd", "bcde", "cdef" diff --git a/examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base_standard_input.json b/examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base_standard_input.json new file mode 100644 index 00000000..971db955 --- /dev/null +++ b/examples/test/semanticTests/array_copying_memory_to_storage_different_base/memory_to_storage_different_base_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory.sol b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory.sol new file mode 100644 index 00000000..e3843537 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +contract C { + function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) { + return _a[1]; + } + + function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) { + return _a[0]; + } + + function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) { + return _a[0]; + } + + function test4(uint16[][] calldata _a) public returns (uint16[][] memory) { + uint16[][][] memory tmp = new uint16[][][](2); + tmp[1] = _a; + return tmp[1]; + } + + function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) { + uint32[][2][] memory tmp = new uint32[][2][](1); + tmp[0] = _a; + return tmp[0]; + } + + function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) { + uint32[2][][] memory tmp = new uint32[2][][](1); + tmp[0] = _a; + return tmp[0]; + } +} +// ---- +// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14 +// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7 +// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 +// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8 diff --git a/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..02d75c60 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_memory/nested_array_element_calldata_to_memory_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage.sol new file mode 100644 index 00000000..5040a72c --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage.sol @@ -0,0 +1,29 @@ +contract C { + uint8[2][2] a; + uint8[2][2][2] a2; + + function test(uint8[2][2][2] calldata _a) public { + a = _a[0]; + require(a[0][0] == 1); + require(a[0][1] == 2); + require(a[1][0] == 3); + require(a[1][1] == 4); + } + + function test2(uint8[2][2] calldata _a) public { + a2[0] = _a; + require(a2[0][0][0] == 1); + require(a2[0][0][1] == 2); + require(a2[0][1][0] == 3); + require(a2[0][1][1] == 4); + require(a2[1][0][0] == 0); + require(a2[1][0][1] == 0); + require(a2[1][1][0] == 0); + require(a2[1][1][1] == 0); + } +} +// ---- +// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 +// test2(uint8[2][2]): 1, 2, 3, 4 +// gas irOptimized: 119939 +// gas legacyOptimized: 120228 diff --git a/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..c19a820a --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_calldata_to_storage/nested_array_element_calldata_to_storage_standard_input.json @@ -0,0 +1,307 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + }, + "bytes_calldata_to_string_calldata.sol": { + "content": "contract C {\n function f(bytes calldata c) public returns (string calldata s) {\n return string(c);\n }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "array_copy_storage_storage_dyn_dyn.sol": { + "content": "\ncontract c {\n uint[] data1;\n uint[] data2;\n function setData1(uint length, uint index, uint value) public {\n data1 = new uint[](length);\n if (index < length)\n data1[index] = value;\n }\n function copyStorageStorage() public { data2 = data1; }\n function getData2(uint index) public returns (uint len, uint val) {\n len = data2.length; if (index < len) val = data2[index];\n }\n}\n// ----\n// setData1(uint256,uint256,uint256): 10, 5, 4 ->\n// copyStorageStorage() ->\n// gas irOptimized: 111350\n// gas legacy: 109272\n// gas legacyOptimized: 109262\n// getData2(uint256): 5 -> 10, 4\n// setData1(uint256,uint256,uint256): 0, 0, 0 ->\n// copyStorageStorage() ->\n// getData2(uint256): 0 -> 0, 0\n// storageEmpty -> 1\n" + }, + "cleanup_during_multi_element_per_slot_copy.sol": { + "content": "contract C {\n uint32[] s;\n constructor()\n {\n s.push();\n s.push();\n }\n function f() external returns (uint)\n {\n (s[1], s) = (4, [0]);\n s = [0];\n s.push();\n return s[1];\n // used to return 4 via IR.\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 90065\n// gas irOptimized code: 149000\n// gas legacy: 89553\n// gas legacy code: 126200\n// gas legacyOptimized: 83556\n// gas legacyOptimized code: 98200\n// f() -> 0\n" + }, + "array_copy_storage_storage_static_dynamic.sol": { + "content": "contract c {\n uint256[9] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[8] = 4;\n data2 = data1;\n x = data2.length;\n y = data2[8];\n }\n}\n// ----\n// test() -> 9, 4\n// gas irOptimized: 123180\n// gas legacy: 123566\n// gas legacyOptimized: 123202\n" + }, + "nested_array_element_calldata_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] calldata _a) public {\n a = _a[0];\n require(a[0][0] == 1);\n require(a[0][1] == 2);\n require(a[1][0] == 3);\n require(a[1][1] == 4);\n }\n\n function test2(uint8[2][2] calldata _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory.sol b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory.sol new file mode 100644 index 00000000..3058df84 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +contract C { + function test1(uint8[][][] memory _a) public returns (uint8[][] memory) { + return _a[1]; + } + + function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) { + return _a[0]; + } + + function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) { + return _a[0]; + } + + function test4(uint16[][] memory _a) public returns (uint16[][] memory) { + uint16[][][] memory tmp = new uint16[][][](2); + tmp[1] = _a; + return tmp[1]; + } + + function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) { + uint32[][2][] memory tmp = new uint32[][2][](1); + tmp[0] = _a; + return tmp[0]; + } + + function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) { + uint32[2][][] memory tmp = new uint32[2][][](1); + tmp[0] = _a; + return tmp[0]; + } +} +// ---- +// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14 +// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7 +// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 +// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8 diff --git a/examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory_standard_input.json new file mode 100644 index 00000000..3c1490bd --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_memory/nested_array_element_memory_to_memory_standard_input.json @@ -0,0 +1,226 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage.sol b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage.sol new file mode 100644 index 00000000..2f4b4ca7 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage.sol @@ -0,0 +1,29 @@ +contract C { + uint8[2][2] a1; + uint8[2][2][2] a2; + + function test(uint8[2][2][2] memory _a) public { + a1 = _a[0]; + require(a1[0][0] == 1); + require(a1[0][1] == 2); + require(a1[1][0] == 3); + require(a1[1][1] == 4); + } + + function test2(uint8[2][2] memory _a) public { + a2[0] = _a; + require(a2[0][0][0] == 1); + require(a2[0][0][1] == 2); + require(a2[0][1][0] == 3); + require(a2[0][1][1] == 4); + require(a2[1][0][0] == 0); + require(a2[1][0][1] == 0); + require(a2[1][1][0] == 0); + require(a2[1][1][1] == 0); + } +} +// ---- +// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8 +// test2(uint8[2][2]): 1, 2, 3, 4 +// gas irOptimized: 119939 +// gas legacyOptimized: 120228 diff --git a/examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage_standard_input.json new file mode 100644 index 00000000..487fb6be --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_memory_to_storage/nested_array_element_memory_to_storage_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory.sol b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory.sol new file mode 100644 index 00000000..e30ca769 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory.sol @@ -0,0 +1,70 @@ +pragma abicoder v2; + +contract C { + uint8[][][] a1 = new uint8[][][](2); + uint8[][][2] a2; + uint8[][2][] a3 = new uint8[][2][](1); + uint8[2][][] a4 = new uint8[2][][](2); + + constructor() { + a1[1] = new uint8[][](2); + a1[1][0] = [3, 4]; + a1[1][1] = [5, 6]; + + a2[0] = new uint8[][](2); + a2[0][0] = [6, 7]; + a2[0][1] = [8, 9]; + a2[1] = new uint8[][](2); + a2[1][0] = [10, 11]; + + a3[0][0] = [3, 4]; + a3[0][1] = [5, 6]; + + a4[0] = new uint8[2][](1); + a4[0][0] = [17, 23]; + a4[1] = new uint8[2][](1); + a4[1][0] = [19, 31]; + } + + function test1() public returns (uint8[][] memory) { + return a1[1]; + } + + function test2() public returns (uint8[][] memory) { + return a2[0]; + } + + function test3() public returns (uint8[][2] memory) { + return a3[0]; + } + + function test4() public returns (uint8[2][] memory) { + return a4[1]; + } + + function test5() public returns (uint8[][][] memory) { + uint8[][][] memory tmp = new uint8[][][](3); + tmp[1] = a1[1]; + return tmp; + } + + function test6() public returns (uint8[][2][] memory) { + uint8[][2][] memory tmp = new uint8[][2][](2); + tmp[0] = a3[0]; + return tmp; + } + + function test7() public returns (uint8[2][][] memory) { + uint8[2][][] memory tmp = new uint8[2][][](1); + tmp[0] = a4[0]; + return tmp; + } +} +// ---- +// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6 +// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9 +// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6 +// test4() -> 0x20, 1, 19, 31 +// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0 +// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0 +// test7() -> 0x20, 1, 0x20, 1, 17, 23 diff --git a/examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory_standard_input.json new file mode 100644 index 00000000..4fe656c0 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_memory/nested_array_element_storage_to_memory_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage.sol b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage.sol new file mode 100644 index 00000000..f3934fec --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage.sol @@ -0,0 +1,84 @@ +pragma abicoder v2; + +contract C { + uint8[][][] src1 = new uint8[][][](2); + uint8[][][2] src2; + uint8[][2][] src3 = new uint8[][2][](1); + uint8[2][][] src4 = new uint8[2][][](2); + + uint8[][] dst1; + uint8[][] dst2; + uint8[][2] dst3; + uint8[][] dst4; + + constructor() { + src1[1] = new uint8[][](2); + src1[1][0] = [3, 4]; + src1[1][1] = [5, 6]; + + src2[0] = new uint8[][](2); + src2[0][0] = [6, 7]; + src2[0][1] = [8, 9]; + src2[1] = new uint8[][](2); + src2[1][0] = [10, 11]; + + src3[0][0] = [3, 4]; + src3[0][1] = [5, 6]; + + src4[0] = new uint8[2][](1); + src4[0][0] = [17, 23]; + src4[1] = new uint8[2][](1); + src4[1][0] = [19, 31]; + } + + function test1() public { + dst1 = src1[1]; + + require(dst1.length == 2); + require(dst1[0][0] == src1[1][0][0]); + require(dst1[0][1] == src1[1][0][1]); + require(dst1[1][0] == src1[1][1][0]); + require(dst1[1][1] == src1[1][1][1]); + } + + function test2() public { + dst2 = src2[0]; + + require(dst2.length == 2); + require(dst2[0][0] == src2[1][0][0]); + require(dst2[0][1] == src2[1][0][1]); + require(dst2[1][0] == src2[1][1][0]); + require(dst2[1][1] == src2[1][1][1]); + } + + function test3() public { + dst3 = src3[0]; + require(dst3[0][0] == src3[0][0][0]); + require(dst3[0][1] == src3[0][0][1]); + require(dst3[1][0] == src3[0][1][0]); + require(dst3[1][1] == src3[0][1][1]); + } + + function test4() public { + dst4 = src4[1]; + require(dst4.length == 2); + require(dst4[0][0] == src4[0][0][0]); + require(dst4[0][1] == src4[0][0][1]); + require(dst4[1][0] == src4[0][1][0]); + require(dst4[1][1] == src4[0][1][1]); + } +} +// ---- +// test1() -> +// gas irOptimized: 150488 +// gas legacy: 150949 +// gas legacyOptimized: 150906 +// test2() -> FAILURE +// gas irOptimized: 150389 +// gas legacy: 150672 +// gas legacyOptimized: 150575 +// test3() -> +// gas irOptimized: 124300 +// gas legacy: 125333 +// gas legacyOptimized: 125127 +// test4() -> FAILURE diff --git a/examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage_standard_input.json new file mode 100644 index 00000000..0abbb9a3 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_element_storage_to_storage/nested_array_element_storage_to_storage_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory.sol b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory.sol new file mode 100644 index 00000000..3d424a7c --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + uint8 y; + } + + function test1(S[1][2] calldata a) public returns (S[1][2] memory) { + return a; + } + + function test2(S[1][] calldata a) public returns (S[1][] memory) { + return a; + } + + function test3(S[][2] calldata a) public returns (S[][2] memory) { + return a; + } +} +// ---- +// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4 +// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23 +// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..940b380c --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_memory/nested_array_of_structs_calldata_to_memory_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage.sol new file mode 100644 index 00000000..7621b247 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][] s1; + S[][1] s2; + S[1][] s3; + + function test1(S[][] calldata _a) public returns (S[][] memory){ + s1 = _a; + return s1; + } + + function test2(S[][1] calldata _a) public returns (S[][1] memory) { + s2 = _a; + return s2; + } + + function test3(S[1][] calldata _a) public returns (S[1][] memory) { + s3 = _a; + return s3; + } +} +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 304788 +// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 116653 +// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 187994 diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..862bf576 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_calldata_to_storage/nested_array_of_structs_calldata_to_storage_standard_input.json @@ -0,0 +1,244 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory.sol b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory.sol new file mode 100644 index 00000000..6c8da98d --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + uint8 y; + } + + function test1(S[1][2] memory a) public returns (S[1][2] memory r) { + r = a; + } + + function test2(S[1][] memory a) public returns (S[1][] memory r) { + r = a; + } + + function test3(S[][2] memory a) public returns (S[][2] memory r) { + r = a; + } +} +// ---- +// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4 +// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23 +// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory_standard_input.json new file mode 100644 index 00000000..65e11770 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_memory/nested_array_of_structs_memory_to_memory_standard_input.json @@ -0,0 +1,241 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage.sol b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage.sol new file mode 100644 index 00000000..8ec3f776 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + S[][] s1; + S[][1] s2; + S[1][] s3; + + function test1(S[][] memory _a) public returns (S[][] memory){ + s1 = _a; + return s1; + } + + function test2(S[][1] memory _a) public returns (S[][1] memory) { + s2 = _a; + return s2; + } + + function test3(S[1][] memory _a) public returns (S[1][] memory) { + s3 = _a; + return s3; + } +} +// ==== +// compileViaYul: true +// ---- +// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 +// gas irOptimized: 309072 +// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 118314 +// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 +// gas irOptimized: 191045 diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage_standard_input.json new file mode 100644 index 00000000..31d03064 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_memory_to_storage/nested_array_of_structs_memory_to_storage_standard_input.json @@ -0,0 +1,292 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage.sol b/examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage.sol new file mode 100644 index 00000000..d0d16915 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage.sol @@ -0,0 +1,69 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + uint8 y; + } + + S[][] src1; + S[][1] src2; + S[1][] src3; + + S[][] dst1; + S[][1] dst2; + S[1][] dst3; + + constructor() { + src1 = new S[][](1); + src1[0].push(S({x: 3, y: 7})); + src1[0].push(S({x: 11, y: 13})); + + src2[0].push(S({x: 3, y: 7})); + src2[0].push(S({x: 11, y: 13})); + src2[0].push(S({x: 17, y: 19})); + + src3.push([S({x: 3, y: 7})]); + src3.push([S({x: 11, y: 13})]); + } + + function test1() public { + dst1 = src1; + + require(dst1.length == 1); + require(dst1[0][0].x == src1[0][0].x); + require(dst1[0][0].y == src1[0][0].y); + require(dst1[0][1].x == src1[0][1].x); + require(dst1[0][1].y == src1[0][1].y); + } + + function test2() public { + dst2 = src2; + + require(dst2[0].length == 3); + require(dst2[0][0].x == src2[0][0].x); + require(dst2[0][0].y == src2[0][0].y); + require(dst2[0][1].x == src2[0][1].x); + require(dst2[0][1].y == src2[0][1].y); + require(dst2[0][2].x == src2[0][2].x); + require(dst2[0][2].y == src2[0][2].y); + } + + function test3() public { + dst3 = src3; + + require(dst3.length == 2); + require(dst3[0][0].x == src3[0][0].x); + require(dst3[0][0].y == src3[0][0].y); + require(dst3[1][0].x == src3[1][0].x); + require(dst3[1][0].y == src3[1][0].y); + } +} +// ==== +// compileViaYul: true +// ---- +// test1() +// gas irOptimized: 123195 +// test2() +// gas irOptimized: 123018 +// test3() diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage_standard_input.json new file mode 100644 index 00000000..5ae338ec --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_storage_to_storage/nested_array_of_structs_storage_to_storage_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol b/examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol new file mode 100644 index 00000000..3a5e44a5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory.sol @@ -0,0 +1,44 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[] a; + uint8[2] b; + } + + uint8[] a1; + uint8[] a2; + uint8[] a3; + + S[][] s1; + S[1][1] s2; + + constructor() { + a1.push(23); + a1.push(29); + a2.push(31); + + s1 = new S[][](2); + s1[0] = new S[](2); + s1[0][0] = S({a: a1, b: [7, 11]}); + s1[0][1] = S({a: a2, b: [17, 19]}); + + s1[1] = new S[](1); + s1[1][0] = S({a: a3, b: [37, 41]}); + + s2[0][0] = S({a: a3, b: [43, 47]}); + } + + function test1() public returns (S[] memory) { + return s1[0]; + } + + function test2() public returns (S[1] memory) { + return s2[0]; + } +} +// ==== +// compileViaYul: true +// ---- +// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31 +// test2() -> 0x20, 0x20, 0x60, 43, 47, 0 diff --git a/examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory_standard_input.json b/examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory_standard_input.json new file mode 100644 index 00000000..16ef511d --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_array_of_structs_with_nested_array_from_storage_to_memory/nested_array_of_structs_with_nested_array_from_storage_to_memory_standard_input.json @@ -0,0 +1,250 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage.sol b/examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage.sol new file mode 100644 index 00000000..57b3dc52 --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage.sol @@ -0,0 +1,36 @@ +pragma abicoder v2; + +contract C { + uint8[][] a; + uint8[][][] a2; + + function test(uint8[][][] calldata _a) public { + a = _a[1]; + require(a.length == 2); + require(a[0].length == 1); + require(a[0][0] == 7); + require(a[1].length == 2); + require(a[1][0] == 8); + require(a[1][1] == 9); + } + + function test2(uint8[][] calldata _a) public { + a2 = new uint8[][][](2); + a2[0] = _a; + require(a2[0].length == 2); + require(a2[0][0].length == 1); + require(a2[0][0][0] == 7); + require(a2[0][1].length == 2); + require(a2[0][1][0] == 8); + require(a2[0][1][1] == 9); + require(a2[1].length == 0); + } +} +// ==== +// compileViaYul: true +// ---- +// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// gas irOptimized: 137897 +// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 +// gas irOptimized: 164482 +// gas legacyOptimized: 120228 diff --git a/examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..35ca6e5b --- /dev/null +++ b/examples/test/semanticTests/array_copying_nested_dynamic_array_element_calldata_to_storage/nested_dynamic_array_element_calldata_to_storage_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested.sol b/examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested.sol new file mode 100644 index 00000000..2a486d25 --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested.sol @@ -0,0 +1,22 @@ +contract C { + uint72[5][] a; + + function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) { + for (uint i = 0; i < 4; i++) + a.push(); + a[0][0] = 1; + a[0][3] = 2; + a[1][1] = 3; + a[1][4] = 4; + a[2][0] = 5; + a[3][2] = 6; + a[3][3] = 7; + uint72[5][] memory m = a; + return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]); + } +} +// ---- +// f() -> 1, 2, 3, 4, 5, 6, 7 +// gas irOptimized: 206440 +// gas legacy: 211758 +// gas legacyOptimized: 211179 diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested_standard_input.json b/examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested_standard_input.json new file mode 100644 index 00000000..060906cb --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested/storage_memory_nested_standard_input.json @@ -0,0 +1,310 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + }, + "dirty_memory_bytes_to_storage_copy.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n // via yul disabled because this truncates the string.\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "copy_removes_bytes_data.sol": { + "content": "\ncontract c {\n function set() public returns (bool) { data1 = msg.data; return true; }\n function reset() public returns (bool) { data1 = data2; return true; }\n bytes data1;\n bytes data2;\n}\n// ----\n// set(): 1, 2, 3, 4, 5 -> true\n// gas irOptimized: 177344\n// gas legacy: 177953\n// gas legacyOptimized: 177550\n// storageEmpty -> 0\n// reset() -> true\n// storageEmpty -> 1\n" + }, + "array_copy_storage_storage_struct.sol": { + "content": "contract c {\n struct Data { uint x; uint y; }\n Data[] data1;\n Data[] data2;\n function test() public returns (uint x, uint y) {\n while (data1.length < 9)\n data1.push();\n data1[8].x = 4;\n data1[8].y = 5;\n data2 = data1;\n x = data2[8].x;\n y = data2[8].y;\n while (data1.length > 0)\n data1.pop();\n data2 = data1;\n }\n}\n// ----\n// test() -> 4, 5\n// gas irOptimized: 190628\n// gas legacy: 190828\n// gas legacyOptimized: 189657\n// storageEmpty -> 1\n" + }, + "array_copy_storage_to_memory_nested.sol": { + "content": "pragma abicoder v2;\ncontract C {\n uint[][] a;\n\n function f() public returns (uint[][] memory) {\n a.push();\n a.push();\n a[0].push(0);\n a[0].push(1);\n a[1].push(2);\n a[1].push(3);\n uint[][] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3\n// gas irOptimized: 161793\n// gas legacy: 162200\n// gas legacyOptimized: 159953\n" + }, + "array_copy_storage_storage_different_base.sol": { + "content": "contract c {\n uint64[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 205667\n// gas legacy: 213863\n// gas legacyOptimized: 212901\n" + }, + "elements_of_nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] calldata _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] calldata _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] calldata _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 327921\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 141162\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 188442\n" + }, + "array_copy_storage_storage_dynamic_dynamic.sol": { + "content": "contract c {\n uint256[] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data2.push(11);\n data1.push(0);\n data1.push(1);\n data1.push(2);\n data1.push(3);\n data1.push(4);\n data2 = data1;\n assert(data1[0] == data2[0]);\n x = data2.length;\n y = data2[4];\n }\n}\n// ----\n// test() -> 5, 4\n// gas irOptimized: 253591\n// gas legacy: 250892\n// gas legacyOptimized: 250045\n" + }, + "array_nested_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n uint256[][] memory a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n uint256[][2] memory a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n uint256[2][] memory a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n uint256[2][2] memory a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n" + }, + "nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] memory _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] memory _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] memory _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 309072\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 118314\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 191045\n" + }, + "bytes_calldata_to_string_calldata.sol": { + "content": "contract C {\n function f(bytes calldata c) public returns (string calldata s) {\n return string(c);\n }\n}\n// ----\n// f(bytes): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "array_copy_storage_storage_dyn_dyn.sol": { + "content": "\ncontract c {\n uint[] data1;\n uint[] data2;\n function setData1(uint length, uint index, uint value) public {\n data1 = new uint[](length);\n if (index < length)\n data1[index] = value;\n }\n function copyStorageStorage() public { data2 = data1; }\n function getData2(uint index) public returns (uint len, uint val) {\n len = data2.length; if (index < len) val = data2[index];\n }\n}\n// ----\n// setData1(uint256,uint256,uint256): 10, 5, 4 ->\n// copyStorageStorage() ->\n// gas irOptimized: 111350\n// gas legacy: 109272\n// gas legacyOptimized: 109262\n// getData2(uint256): 5 -> 10, 4\n// setData1(uint256,uint256,uint256): 0, 0, 0 ->\n// copyStorageStorage() ->\n// getData2(uint256): 0 -> 0, 0\n// storageEmpty -> 1\n" + }, + "cleanup_during_multi_element_per_slot_copy.sol": { + "content": "contract C {\n uint32[] s;\n constructor()\n {\n s.push();\n s.push();\n }\n function f() external returns (uint)\n {\n (s[1], s) = (4, [0]);\n s = [0];\n s.push();\n return s[1];\n // used to return 4 via IR.\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 90065\n// gas irOptimized code: 149000\n// gas legacy: 89553\n// gas legacy code: 126200\n// gas legacyOptimized: 83556\n// gas legacyOptimized code: 98200\n// f() -> 0\n" + }, + "array_copy_storage_storage_static_dynamic.sol": { + "content": "contract c {\n uint256[9] data1;\n uint256[] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[8] = 4;\n data2 = data1;\n x = data2.length;\n y = data2[8];\n }\n}\n// ----\n// test() -> 9, 4\n// gas irOptimized: 123180\n// gas legacy: 123566\n// gas legacyOptimized: 123202\n" + }, + "nested_array_element_calldata_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] calldata _a) public {\n a = _a[0];\n require(a[0][0] == 1);\n require(a[0][1] == 2);\n require(a[1][0] == 3);\n require(a[1][1] == 4);\n }\n\n function test2(uint8[2][2] calldata _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "storage_memory_nested.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] memory m = a;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211758\n// gas legacyOptimized: 211179\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes.sol b/examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes.sol new file mode 100644 index 00000000..e5a6ae53 --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; +contract C { + bytes[] a; + + function f() public returns (bytes[] memory) { + a.push("abc"); + a.push("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ"); + bytes[] memory m = a; + return m; + } +} +// ---- +// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 +// gas irOptimized: 202083 +// gas legacy: 204327 +// gas legacyOptimized: 202899 diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes_standard_input.json b/examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes_standard_input.json new file mode 100644 index 00000000..c94d9c1c --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested_bytes/storage_memory_nested_bytes_standard_input.json @@ -0,0 +1,193 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer.sol b/examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer.sol new file mode 100644 index 00000000..5ec2cbcf --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer.sol @@ -0,0 +1,23 @@ +contract C { + uint72[5][] a; + + function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) { + for (uint i = 0; i < 4; i++) + a.push(); + a[0][0] = 1; + a[0][3] = 2; + a[1][1] = 3; + a[1][4] = 4; + a[2][0] = 5; + a[3][2] = 6; + a[3][3] = 7; + uint72[5][] storage a_ = a; + uint72[5][] memory m = a_; + return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]); + } +} +// ---- +// f() -> 1, 2, 3, 4, 5, 6, 7 +// gas irOptimized: 206440 +// gas legacy: 211770 +// gas legacyOptimized: 211191 diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer_standard_input.json b/examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer_standard_input.json new file mode 100644 index 00000000..59f8dada --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested_from_pointer/storage_memory_nested_from_pointer_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct.sol b/examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct.sol new file mode 100644 index 00000000..b37aa96e --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct.sol @@ -0,0 +1,29 @@ +contract C { + struct T { uint8 x; uint8 y; uint[] z; } + T[3][] a; + + function f() public returns (uint8, uint8, uint, uint8, uint8, uint) { + a.push(); + a.push(); + a[0][1].x = 11; + a[0][1].y = 12; + a[0][1].z.push(1); + a[0][1].z.push(2); + a[0][1].z.push(3); + a[1][2].x = 21; + a[1][2].y = 22; + a[1][2].z.push(4); + a[1][2].z.push(5); + a[1][2].z.push(6); + T[3][] memory m = a; + return ( + m[0][1].x, m[0][1].y, m[0][1].z[0], + m[1][2].x, m[1][2].y, m[1][2].z[0] + ); + } +} +// ---- +// f() -> 11, 0x0c, 1, 0x15, 22, 4 +// gas irOptimized: 291212 +// gas legacy: 293398 +// gas legacyOptimized: 290218 diff --git a/examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct_standard_input.json b/examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct_standard_input.json new file mode 100644 index 00000000..bfd7d3e5 --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_nested_struct/storage_memory_nested_struct_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed.sol b/examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed.sol new file mode 100644 index 00000000..f49b4923 --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed.sol @@ -0,0 +1,13 @@ +contract C { + uint8[33] a; + + function f() public returns (uint8, uint8, uint8) { + a[0] = 2; + a[16] = 3; + a[32] = 4; + uint8[33] memory m = a; + return (m[0], m[16], m[32]); + } +} +// ---- +// f() -> 2, 3, 4 diff --git a/examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed_standard_input.json b/examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed_standard_input.json new file mode 100644 index 00000000..1e23d168 --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_packed/storage_memory_packed_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn.sol b/examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn.sol new file mode 100644 index 00000000..a8a1b36e --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn.sol @@ -0,0 +1,18 @@ +contract C { + uint8[] a; + + function f() public returns (uint8, uint8, uint8) { + for (uint i = 0; i < 33; i++) + a.push(7); + a[0] = 2; + a[16] = 3; + a[32] = 4; + uint8[] memory m = a; + return (m[0], m[16], m[32]); + } +} +// ---- +// f() -> 2, 3, 4 +// gas irOptimized: 114338 +// gas legacy: 122231 +// gas legacyOptimized: 118409 diff --git a/examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn_standard_input.json b/examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn_standard_input.json new file mode 100644 index 00000000..91958390 --- /dev/null +++ b/examples/test/semanticTests/array_copying_storage_memory_packed_dyn/storage_memory_packed_dyn_standard_input.json @@ -0,0 +1,265 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + }, + "nested_dynamic_array_element_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][] a;\n uint8[][][] a2;\n\n function test(uint8[][][] calldata _a) public {\n a = _a[1];\n require(a.length == 2);\n require(a[0].length == 1);\n require(a[0][0] == 7);\n require(a[1].length == 2);\n require(a[1][0] == 8);\n require(a[1][1] == 9);\n }\n\n function test2(uint8[][] calldata _a) public {\n a2 = new uint8[][][](2);\n a2[0] = _a;\n require(a2[0].length == 2);\n\trequire(a2[0][0].length == 1);\n\trequire(a2[0][0][0] == 7);\n\trequire(a2[0][1].length == 2);\n\trequire(a2[0][1][0] == 8);\n\trequire(a2[0][1][1] == 9);\n\trequire(a2[1].length == 0);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 137897\n// test2(uint8[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// gas irOptimized: 164482\n// gas legacyOptimized: 120228\n" + }, + "copy_byte_array_in_struct_to_storage.sol": { + "content": "pragma abicoder v2;\nstruct S {\n uint16 x;\n bytes a;\n uint16 y;\n bytes b;\n}\ncontract C {\n uint padding;\n S data;\n\n function f() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.a = \"abcdef\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function g() public returns (bytes memory, bytes memory) {\n S memory x;\n x.x = 7;\n x.b = \"12345678923456789\";\n x.a = \"1234567890123456789012345678901 1234567890123456789012345678901 123456789\";\n x.y = 9;\n data = x;\n return (data.a, data.b);\n }\n function h() public returns (bytes memory, bytes memory) {\n S memory x;\n data = x;\n return (data.a, data.b);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000\n// gas irOptimized: 179405\n// gas legacy: 180675\n// gas legacyOptimized: 179686\n// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000\n// gas irOptimized: 106338\n// gas legacy: 109415\n// gas legacyOptimized: 106600\n// h() -> 0x40, 0x60, 0x00, 0x00\n// storageEmpty -> 1\n" + }, + "elements_of_nested_array_of_structs_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][][] s1;\n S[][1][] s2;\n S[1][][1] s3;\n\n function test1(S[][][] memory _a) public returns (S[][] memory){\n s1.push();\n s1[0] = _a[0];\n return s1[0];\n }\n\n function test2(S[][1][] memory _a) public returns (S[][1] memory) {\n s2.push();\n s2[0] = _a[0];\n return s2[0];\n }\n\n function test3(S[1][][2] memory _a) public returns (S[1][] memory) {\n s3[0] = _a[1];\n return s3[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][][]): 0x20, 1, 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 332567\n// test2((uint8[],uint8[2])[][1][]): 0x20, 2, 0x40, 0x0160, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13, 0x20, 1, 0x20, 0x60, 31, 37, 2, 23, 29 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 145409\n// test3((uint8[],uint8[2])[1][][2]): 0x20, 0x40, 0x60, 0, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 288, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 192248\n" + }, + "nested_array_of_structs_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] calldata a) public returns (S[1][2] memory) {\n return a;\n }\n\n function test2(S[1][] calldata a) public returns (S[1][] memory) {\n return a;\n }\n\n function test3(S[][2] calldata a) public returns (S[][2] memory) {\n return a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "array_copy_clear_storage_packed.sol": { + "content": "contract C {\n uint128[] x;\n uint64[] x1;\n uint120[] x2;\n function f() public returns(uint128) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[0] == 23);\n assert(x[2] == 0);\n assert(x[3] == 0);\n return x[1];\n }\n\n function g() public returns(uint64) {\n x1.push(42); x1.push(42); x1.push(42); x1.push(42);\n uint64[] memory y = new uint64[](1);\n y[0] = 23;\n x1 = y;\n assembly { sstore(x1.slot, 4) }\n assert(x1[0] == 23);\n assert(x1[2] == 0);\n assert(x1[3] == 0);\n return x1[1];\n }\n\n function h() public returns(uint120) {\n x2.push(42); x2.push(42); x2.push(42); x2.push(42);\n uint120[] memory y = new uint120[](1);\n y[0] = 23;\n x2 = y;\n assembly { sstore(x2.slot, 4) }\n assert(x2[0] == 23);\n assert(x2[2] == 0);\n assert(x2[3] == 0);\n return x2[1];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 92800\n// gas legacy: 93006\n// gas legacyOptimized: 92261\n// g() -> 0\n// h() -> 0\n// gas irOptimized: 92862\n// gas legacy: 93028\n// gas legacyOptimized: 92303\n" + }, + "dirty_memory_bytes_to_storage_copy_ir.sol": { + "content": "contract C {\n bytes x;\n function f() public returns (uint r) {\n bytes memory m = \"tmp\";\n assembly {\n mstore(m, 8)\n mstore(add(m, 32), \"deadbeef15dead\")\n }\n x = m;\n assembly {\n r := sload(x.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x6465616462656566000000000000000000000000000000000000000000000010\n" + }, + "calldata_array_dynamic_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[] s;\n function f(uint256[] calldata data) external returns (uint) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1\n// gas irOptimized: 111084\n// gas legacy: 111548\n// gas legacyOptimized: 111321\n" + }, + "nested_array_element_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] a1 = new uint8[][][](2);\n uint8[][][2] a2;\n uint8[][2][] a3 = new uint8[][2][](1);\n uint8[2][][] a4 = new uint8[2][][](2);\n\n constructor() {\n a1[1] = new uint8[][](2);\n a1[1][0] = [3, 4];\n a1[1][1] = [5, 6];\n\n a2[0] = new uint8[][](2);\n a2[0][0] = [6, 7];\n a2[0][1] = [8, 9];\n a2[1] = new uint8[][](2);\n a2[1][0] = [10, 11];\n\n a3[0][0] = [3, 4];\n a3[0][1] = [5, 6];\n\n a4[0] = new uint8[2][](1);\n a4[0][0] = [17, 23];\n a4[1] = new uint8[2][](1);\n a4[1][0] = [19, 31];\n }\n\n function test1() public returns (uint8[][] memory) {\n return a1[1];\n }\n\n function test2() public returns (uint8[][] memory) {\n return a2[0];\n }\n\n function test3() public returns (uint8[][2] memory) {\n return a3[0];\n }\n\n function test4() public returns (uint8[2][] memory) {\n return a4[1];\n }\n\n function test5() public returns (uint8[][][] memory) {\n uint8[][][] memory tmp = new uint8[][][](3);\n tmp[1] = a1[1];\n return tmp;\n }\n\n function test6() public returns (uint8[][2][] memory) {\n uint8[][2][] memory tmp = new uint8[][2][](2);\n tmp[0] = a3[0];\n return tmp;\n }\n\n function test7() public returns (uint8[2][][] memory) {\n uint8[2][][] memory tmp = new uint8[2][][](1);\n tmp[0] = a4[0];\n return tmp;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test2() -> 0x20, 2, 0x40, 0xa0, 2, 6, 7, 2, 8, 9\n// test3() -> 0x20, 0x40, 0xa0, 2, 3, 4, 2, 5, 6\n// test4() -> 0x20, 1, 19, 31\n// test5() -> 0x20, 3, 0x60, 0x80, 0x01a0, 0, 2, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0\n// test6() -> 0x20, 2, 0x40, 0x0140, 0x40, 0xa0, 2, 3, 4, 2, 5, 6, 0x40, 0x60, 0, 0\n// test7() -> 0x20, 1, 0x20, 1, 17, 23\n" + }, + "array_copy_storage_storage_static_static.sol": { + "content": "contract c {\n uint256[40] data1;\n uint256[20] data2;\n\n function test() public returns (uint256 x, uint256 y) {\n data1[30] = 4;\n data1[2] = 7;\n data1[3] = 9;\n data2[3] = 8;\n data1 = data2;\n x = data1[3];\n y = data1[30]; // should be cleared\n }\n}\n// ----\n// test() -> 8, 0\n// gas irOptimized: 196251\n// gas legacy: 194842\n// gas legacyOptimized: 194281\n" + }, + "calldata_dynamic_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a)\n external\n returns (uint256, uint256[] memory)\n {\n uint256[] memory m = a[0];\n return (a.length, m);\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x17, 0x2a -> 0x1, 0x40, 0x2, 0x17, 0x2a\n" + }, + "copy_function_internal_storage_array.sol": { + "content": "contract C {\n function() internal returns (uint)[] x;\n function() internal returns (uint)[] y;\n\n function test() public returns (uint256) {\n x = new function() internal returns (uint)[](10);\n x[9] = a;\n y = x;\n return y[9]();\n }\n\n function a() public returns (uint256) {\n return 7;\n }\n}\n// ----\n// test() -> 7\n// gas irOptimized: 122459\n// gas legacy: 205176\n// gas legacyOptimized: 204971\n" + }, + "array_copy_nested_array.sol": { + "content": "contract c {\n uint256[4][] a;\n uint256[10][] b;\n uint256[][] c;\n\n function test(uint256[2][] calldata d) external returns (uint256) {\n a = d;\n b = a;\n c = b;\n return c[1][1] | c[1][2] | c[1][3] | c[1][4];\n }\n}\n// ----\n// test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10\n// gas irOptimized: 689552\n// gas legacy: 686176\n// gas legacyOptimized: 685611\n" + }, + "array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = sPtr;\n return m[0];\n }\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = a;\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 147755\n// gas legacy: 148892\n// gas legacyOptimized: 146917\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_target_simple_2.sol": { + "content": "contract c {\n bytes9[7] data1; // 3 per slot\n bytes32[10] data2; // 1 per slot\n\n function test()\n public\n returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00\n// gas irOptimized: 232995\n// gas legacy: 235694\n// gas legacyOptimized: 235193\n" + }, + "array_copy_storage_to_memory.sol": { + "content": "contract C {\n uint[] a;\n function f() public returns (uint, uint) {\n a.push(1); a.push(0); a.push(0);\n uint[] memory b = a;\n return (b[0], b.length);\n }\n}\n// ----\n// f() -> 1, 3\n" + }, + "function_type_array_to_storage.sol": { + "content": "contract C {\n\tstring log;\n\tfunction() external[] fs;\n\tfunction() external[] gs;\n\n\tfunction a() external {\n\t\tlog = string.concat(log, \"[a called]\");\n\t}\n\tfunction b() external {\n\t\tlog = string.concat(log, \"[b called]\");\n\t}\n\n\tfunction f(function() external[] calldata x) external {\n\t\tfs = x;\n\t}\n\tfunction g(function() external[] memory x) public {\n\t\tfs = x;\n\t}\n\tfunction test() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.a;\n\t\tx[1] = this.b;\n\t\tthis.f(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test2() external returns (string memory) {\n\t\tlog = \"\";\n\t\tfunction() external[] memory x = new function() external[](2);\n\t\tx[0] = this.b;\n\t\tx[1] = this.a;\n\t\tg(x);\n\t\tfs[0]();\n\t\tfs[1]();\n\t\treturn log;\n\t}\n\tfunction test3() external returns (string memory) {\n\t\tlog = \"\";\n\t\tgs = fs;\n\t\tgs[0]();\n\t\tgs[1]();\n\t\treturn log;\n\t}\n}\n// ----\n// test() -> 0x20, 0x14, \"[a called][b called]\"\n// gas irOptimized: 116518\n// gas legacy: 118841\n// gas legacyOptimized: 116843\n// test2() -> 0x20, 0x14, \"[b called][a called]\"\n// test3() -> 0x20, 0x14, \"[b called][a called]\"\n// gas irOptimized: 103144\n// gas legacy: 102654\n// gas legacyOptimized: 101556\n" + }, + "array_storage_multi_items_per_slot.sol": { + "content": "contract C {\n uint8[33] a;\n uint32[9] b;\n uint120[3] c;\n\n function f() public returns (uint8, uint32, uint120) {\n a[32] = 1; a[31] = 2; a[30] = 3;\n b[0] = 1; b[1] = 2; b[2] = 3;\n c[2] = 3; c[1] = 1;\n return (a[32], b[1], c[2]);\n }\n}\n// ----\n// f() -> 1, 2, 3\n// gas irOptimized: 131939\n// gas legacy: 134605\n// gas legacyOptimized: 131938\n" + }, + "storage_memory_packed.sol": { + "content": "contract C {\n uint8[33] a;\n\n function f() public returns (uint8, uint8, uint8) {\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[33] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n" + }, + "memory_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f() external returns (uint256, bytes10, bytes10, bytes10) {\n bytes4[] memory m = new bytes4[](3);\n m[0] = \"abcd\";\n m[1] = \"bcde\";\n m[2] = \"cdef\";\n s = m;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f() -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "bytes_storage_to_memory.sol": { + "content": "contract C {\n bytes s = \"abcd\";\n function f() external returns (bytes1) {\n bytes memory data = s;\n return data[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "array_copy_different_packing.sol": { + "content": "contract c {\n bytes8[] data1; // 4 per slot\n bytes10[] data2; // 3 per slot\n\n function test()\n public\n returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e)\n {\n data1 = new bytes8[](9);\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[5];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000\n// gas irOptimized: 208415\n// gas legacy: 220711\n// gas legacyOptimized: 220097\n" + }, + "calldata_bytes_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f(bytes calldata data) external returns (bytes1) {\n s = data;\n return s[0];\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> \"a\"\n" + }, + "array_of_struct_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f(S[] calldata c) public returns (uint128, uint64, uint128) {\n s = c;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// gas irOptimized: 120747\n" + }, + "calldata_1d_array_into_2d_memory_array_element.sol": { + "content": "// Example from https://github.com/ethereum/solidity/issues/12558\npragma abicoder v2;\ncontract C {\n function f(uint[] calldata a) external returns (uint[][] memory) {\n uint[][] memory m = new uint[][](2);\n m[0] = a;\n\n return m;\n }\n}\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n uint[] memory arr = new uint[](4);\n\n arr[0] = 13;\n arr[1] = 14;\n arr[2] = 15;\n arr[3] = 16;\n\n uint[][] memory ret = c.f(arr);\n assert(ret.length == 2);\n assert(ret[0].length == 4);\n assert(ret[0][0] == 13);\n assert(ret[0][1] == 14);\n assert(ret[0][2] == 15);\n assert(ret[0][3] == 16);\n assert(ret[1].length == 0);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "array_copy_target_simple.sol": { + "content": "contract c {\n bytes8[9] data1; // 4 per slot\n bytes17[10] data2; // 1 per slot, no offset counter\n\n function test()\n public\n returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e)\n {\n for (uint256 i = 0; i < data1.length; ++i) data1[i] = bytes8(uint64(i));\n data2[8] = data2[9] = bytes8(uint64(2));\n data2 = data1;\n a = data2[1];\n b = data2[2];\n c = data2[3];\n d = data2[4];\n e = data2[9];\n }\n}\n// ----\n// test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0\n// gas irOptimized: 273543\n// gas legacy: 282601\n// gas legacyOptimized: 281510\n" + }, + "storage_memory_nested_struct.sol": { + "content": "contract C {\n struct T { uint8 x; uint8 y; uint[] z; }\n T[3][] a;\n\n function f() public returns (uint8, uint8, uint, uint8, uint8, uint) {\n a.push();\n a.push();\n a[0][1].x = 11;\n a[0][1].y = 12;\n a[0][1].z.push(1);\n a[0][1].z.push(2);\n a[0][1].z.push(3);\n a[1][2].x = 21;\n a[1][2].y = 22;\n a[1][2].z.push(4);\n a[1][2].z.push(5);\n a[1][2].z.push(6);\n T[3][] memory m = a;\n return (\n m[0][1].x, m[0][1].y, m[0][1].z[0],\n m[1][2].x, m[1][2].y, m[1][2].z[0]\n );\n }\n}\n// ----\n// f() -> 11, 0x0c, 1, 0x15, 22, 4\n// gas irOptimized: 291212\n// gas legacy: 293398\n// gas legacyOptimized: 290218\n" + }, + "calldata_nested_array_copy_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract Test {\n struct shouldBug {\n uint256[][2] deadly;\n }\n function killer(uint256[][2] calldata weapon) pure external returns (shouldBug memory) {\n return shouldBug(weapon);\n }\n}\n// ----\n// killer(uint256[][2]): 0x20, 0x40, 0x40, 2, 1, 2 -> 0x20, 0x20, 0x40, 0xa0, 2, 1, 2, 2, 1, 2\n" + }, + "nested_array_element_memory_to_storage.sol": { + "content": "contract C {\n uint8[2][2] a1;\n uint8[2][2][2] a2;\n\n function test(uint8[2][2][2] memory _a) public {\n a1 = _a[0];\n require(a1[0][0] == 1);\n require(a1[0][1] == 2);\n require(a1[1][0] == 3);\n require(a1[1][1] == 4);\n }\n\n function test2(uint8[2][2] memory _a) public {\n a2[0] = _a;\n require(a2[0][0][0] == 1);\n require(a2[0][0][1] == 2);\n require(a2[0][1][0] == 3);\n require(a2[0][1][1] == 4);\n require(a2[1][0][0] == 0);\n require(a2[1][0][1] == 0);\n require(a2[1][1][0] == 0);\n require(a2[1][1][1] == 0);\n }\n}\n// ----\n// test(uint8[2][2][2]): 1, 2, 3, 4, 5, 6, 7, 8\n// test2(uint8[2][2]): 1, 2, 3, 4\n// gas irOptimized: 119939\n// gas legacyOptimized: 120228\n" + }, + "calldata_array_static_to_memory.sol": { + "content": "contract C {\n function f(uint256[2] calldata c) public returns (uint256, uint256) {\n uint256[2] memory m1 = c;\n return (m1[0], m1[1]);\n }\n}\n// ----\n// f(uint256[2]): 43, 57 -> 43, 57\n" + }, + "array_elements_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n constructor() {\n s = new uint8[][](2);\n\n s[0] = new uint8[](2);\n s[0][0] = 10;\n s[0][1] = 11;\n\n s[1] = new uint8[](3);\n s[1][0] = 12;\n s[1][1] = 13;\n s[1][2] = 14;\n }\n\n function from_storage() public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = s[0];\n m[0][1] = s[1];\n return m[0];\n }\n\n\n function from_storage_ptr() public returns (uint8[][] memory) {\n uint8[][] storage sPtr = s;\n m[0] = new uint8[][](2);\n m[0][0] = sPtr[0];\n m[0][1] = sPtr[1];\n return m[0];\n }\n\n\n function from_memory() public returns (uint8[][] memory) {\n uint8[][] memory a = s;\n m[0] = new uint8[][](2);\n m[0][0] = a[0];\n m[0][1] = a[1];\n return m[0];\n }\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = new uint8[][](2);\n m[0][0] = _a[0];\n m[0][1] = _a[1];\n return m[0];\n }\n}\n// ----\n// from_storage() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 149868\n// gas legacy: 150737\n// gas legacyOptimized: 148690\n// from_storage_ptr() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_memory() -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n" + }, + "array_copy_memory_to_storage.sol": { + "content": "contract C {\n uint128[13] unused;\n uint32[] a;\n uint32[3] b;\n function f() public returns (uint32, uint256) {\n uint32[] memory m = new uint32[](3);\n m[0] = 1;\n m[1] = 2;\n m[2] = 3;\n a = m;\n assert(a[0] == m[0]);\n assert(a[1] == m[1]);\n assert(a[2] == m[2]);\n return (a[0], a.length);\n }\n function g() public returns (uint32, uint32, uint32) {\n uint32[3] memory m;\n m[0] = 1; m[1] = 2; m[2] = 3;\n a = m;\n b = m;\n assert(a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);\n assert(a.length == b.length);\n return (a[0], b[1], a[2]);\n }\n}\n// ----\n// f() -> 1, 3\n// g() -> 1, 2, 3\n" + }, + "array_of_structs_containing_arrays_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint136 p;\n uint128[3] b;\n uint128[] c;\n }\n\n S[] s;\n\n function f() external returns (uint256, uint256, uint128, uint128) {\n S[] memory m = new S[](3);\n m[1] = S(0, [uint128(1), 2, 3], new uint128[](3));\n m[1].c[0] = 1;\n m[1].c[1] = 2;\n m[1].c[2] = 3;\n s = m;\n assert(s.length == m.length);\n assert(s[1].b[1] == m[1].b[1]);\n assert(s[1].c[0] == m[1].c[0]);\n return (s[1].b.length, s[1].c.length, s[1].b[2], s[1].c[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 3, 3, 3, 1\n// gas irOptimized: 181928\n" + }, + "calldata_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal returns (bytes memory) {\n return m[0];\n }\n function f(bytes[2] calldata c) external returns (bytes memory) {\n return g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" -> 0x20, 2, \"ab\"\n" + }, + "array_nested_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n function test1(uint256[][] calldata c) external returns (uint256, uint256) {\n a1 = c;\n assert(a1[0][0] == c[0][0]);\n assert(a1[0][1] == c[0][1]);\n return (a1.length, a1[0][0] + a1[1][1]);\n }\n\n function test2(uint256[][2] calldata c) external returns (uint256, uint256) {\n a2 = c;\n assert(a2[0][0] == c[0][0]);\n assert(a2[0][1] == c[0][1]);\n return (a2[0].length, a2[0][0] + a2[1][1]);\n }\n\n function test3(uint256[2][] calldata c) external returns (uint256, uint256) {\n a3 = c;\n assert(a3[0][0] == c[0][0]);\n assert(a3[0][1] == c[0][1]);\n return (a3.length, a3[0][0] + a3[1][1]);\n }\n\n function test4(uint256[2][2] calldata c) external returns (uint256) {\n a4 = c;\n assert(a4[0][0] == c[0][0]);\n assert(a4[0][1] == c[0][1]);\n return (a4[0][0] + a4[1][1]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 181029\n// test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65\n// gas irOptimized: 157604\n// test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65\n// gas irOptimized: 134801\n// test4(uint256[2][2]): 23, 42, 23, 42 -> 65\n// gas irOptimized: 111177\n" + }, + "calldata_array_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n mapping (uint => uint8[][]) m;\n\n uint8[][] s;\n\n function from_calldata(uint8[][] calldata _a) public returns (uint8[][] memory) {\n m[0] = _a;\n return m[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// from_calldata(uint8[][]): 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14 -> 0x20, 2, 0x40, 0xa0, 2, 10, 11, 3, 12, 13, 14\n// gas irOptimized: 139587\n" + }, + "bytes_memory_to_storage.sol": { + "content": "contract C {\n bytes s;\n function f() external returns (bytes1) {\n bytes memory data = \"abcd\";\n s = data;\n return s[0];\n }\n}\n// ----\n// f() -> \"a\"\n" + }, + "storage_memory_nested_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public returns (bytes[] memory) {\n a.push(\"abc\");\n a.push(\"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ\");\n bytes[] memory m = a;\n return m;\n }\n}\n// ----\n// f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000\n// gas irOptimized: 202083\n// gas legacy: 204327\n// gas legacyOptimized: 202899\n" + }, + "array_of_struct_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n function f(S[3] calldata c) public returns (uint128, uint64, uint128) {\n S[3] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n function g(S[] calldata c) public returns (uint128, uint64, uint128) {\n S[] memory m = c;\n return (m[2].a, m[1].b, m[0].c);\n }\n}\n// ----\n// f((uint128,uint64,uint128)[3]): 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n// g((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12\n" + }, + "copying_bytes_multiassign.sol": { + "content": "contract receiver {\n uint public received;\n function recv(uint x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver(); }\n fallback() external { savedData1 = savedData2 = msg.data; }\n function forward(bool selector) public returns (bool) {\n if (selector) { address(rec).call(savedData1); delete savedData1; }\n else { address(rec).call(savedData2); delete savedData2; }\n return true;\n }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData1;\n bytes savedData2;\n}\n// ----\n// (): 7 ->\n// gas irOptimized: 110822\n// gas legacy: 111388\n// gas legacyOptimized: 111065\n// val() -> 0\n// forward(bool): true -> true\n// val() -> 0x80\n// forward(bool): false -> true\n// val() -> 0x80\n// forward(bool): true -> true\n// val() -> 0x80\n" + }, + "array_copy_calldata_storage.sol": { + "content": "contract c {\n uint[9] m_data;\n uint[] m_data_dyn;\n uint8[][] m_byte_data;\n function store(uint[9] calldata a, uint8[3][] calldata b) external returns (uint8) {\n m_data = a;\n m_data_dyn = a;\n m_byte_data = b;\n return b[3][1]; // note that access and declaration are reversed to each other\n }\n function retrieve() public returns (uint a, uint b, uint c, uint d, uint e, uint f, uint g) {\n a = m_data.length;\n b = m_data[7];\n c = m_data_dyn.length;\n d = m_data_dyn[7];\n e = m_byte_data.length;\n f = m_byte_data[3].length;\n g = m_byte_data[3][1];\n }\n}\n// ----\n// store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32\n// gas irOptimized: 647725\n// gas legacy: 694354\n// gas legacyOptimized: 693849\n// retrieve() -> 9, 28, 9, 28, 4, 3, 32\n" + }, + "array_copy_target_leftover2.sol": { + "content": "// since the copy always copies whole slots, we have to make sure that the source size maxes\n// out a whole slot and at the same time there are still elements left in the target at that point\ncontract c {\n bytes8[4] data1; // fits into one slot\n bytes10[6] data2; // 4 elements need two slots\n\n function test() public returns (bytes10 r1, bytes10 r2, bytes10 r3) {\n data1[0] = bytes8(uint64(1));\n data1[1] = bytes8(uint64(2));\n data1[2] = bytes8(uint64(3));\n data1[3] = bytes8(uint64(4));\n for (uint256 i = 0; i < data2.length; ++i)\n data2[i] = bytes10(uint80(0xffff00 | (1 + i)));\n data2 = data1;\n r1 = data2[3];\n r2 = data2[4];\n r3 = data2[5];\n }\n}\n// ----\n// test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0\n// gas irOptimized: 93858\n// gas legacy: 97451\n// gas legacyOptimized: 94200\n" + }, + "copy_byte_array_to_storage.sol": { + "content": "function dataslot() pure returns (bytes32) {\n return keccak256(abi.encode(1));\n}\n\nfunction readDataSlot(uint offset) view returns (bytes32 r) {\n bytes32 s = dataslot();\n assembly { r := sload(add(s, offset)) }\n}\n\nfunction readDataSlot() view returns (bytes32) {\n return readDataSlot(0);\n}\n\nfunction readHead() view returns (bytes32 r) {\n assembly { r := sload(1) }\n}\n\ncontract C {\n uint padding;\n bytes data;\n\n function f() public returns (uint) {\n bytes32 zero;\n if (!(readDataSlot() == zero)) return 1;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 2;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n if (!(readDataSlot() != zero)) return 3;\n if (!(readDataSlot(1) != zero)) return 4;\n if (!(readDataSlot(2) != zero)) return 5;\n if (!(readDataSlot(3) == zero)) return 6;\n if (!(readDataSlot(4) == zero)) return 7;\n data = \"abc\";\n if (!(readDataSlot() == zero)) return 8;\n if (!(readDataSlot(1) == zero)) return 9;\n if (!(readDataSlot(2) == zero)) return 10;\n if (!(readDataSlot(3) == zero)) return 11;\n data = \"1234567890123456789012345678901234567890123456789012345678901234567890\";\n data = \"123456789012345678901234567890123456\";\n if (!(readDataSlot() != zero)) return 12;\n if (!(readDataSlot(1) != zero)) return 13;\n if (!(readDataSlot(2) == zero)) return 14;\n if (!(readDataSlot(3) == zero)) return 15;\n return 0xff;\n }\n}\n// ----\n// f() -> 0xff\n// gas irOptimized: 143857\n// gas legacy: 153404\n// gas legacyOptimized: 146676\n" + }, + "array_copy_cleanup_uint40.sol": { + "content": "// Issue 9832: Test to see if cleanup is performed properly after array copying\ncontract C {\n uint40[] x;\n function f() public returns(bool) {\n\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n x.push(42); x.push(42); x.push(42); x.push(42);\n\n uint40[] memory y = new uint40[](1);\n y[0] = 23;\n x = y;\n\n assembly { sstore(x.slot, 20) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n assert(x[2] == 0);\n assert(x[3] == 0);\n\n assert(x[4] == 0);\n assert(x[5] == 0);\n assert(x[6] == 0);\n assert(x[7] == 0);\n\n assert(x[8] == 0);\n assert(x[9] == 0);\n assert(x[10] == 0);\n assert(x[11] == 0);\n\n assert(x[12] == 0);\n assert(x[13] == 0);\n assert(x[14] == 0);\n assert(x[15] == 0);\n\n assert(x[16] == 0);\n assert(x[17] == 0);\n assert(x[18] == 0);\n assert(x[19] == 0);\n\n return true;\n\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 122541\n// gas legacy: 124643\n// gas legacyOptimized: 122801\n" + }, + "array_copy_storage_storage_different_base_nested.sol": { + "content": "contract c {\n uint48[5][2] data1;\n uint120[6][3] data2;\n\n function test() public returns (uint256 x, uint120 y) {\n data2[0][0] = 11;\n data2[1][0] = 22;\n data2[2][0] = 33;\n\n data1[0][0] = 0;\n data1[0][1] = 1;\n data1[0][2] = 2;\n data1[0][3] = 3;\n data1[0][4] = 4;\n data1[1][0] = 3;\n data2 = data1;\n assert(data1[0][1] == data2[0][1]);\n x = data2.length;\n y = data2[0][4];\n }\n}\n// ----\n// test() -> 3, 4\n// gas irOptimized: 169669\n// gas legacy: 175415\n// gas legacyOptimized: 172533\n" + }, + "array_of_struct_memory_to_storage.sol": { + "content": "contract C {\n struct S {\n uint128 a;\n uint64 b;\n uint128 c;\n }\n uint128[137] unused;\n S[] s;\n function f() public returns (uint128, uint64, uint128) {\n S[] memory m = new S[](3);\n m[2].a = 10;\n m[1].b = 11;\n m[0].c = 12;\n s = m;\n return (s[2].a, s[1].b, s[0].c);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 10, 11, 12\n// gas irOptimized: 118796\n" + }, + "calldata_to_storage_different_base.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes10[] s;\n function f(bytes8[] calldata c) external returns (uint256, bytes10, bytes10, bytes10) {\n s = c;\n return (s.length, s[0], s[1], s[2]);\n }\n}\n// ----\n// f(bytes8[]): 0x20, 3, \"abcd\", \"bcde\", \"cdef\" -> 3, \"abcd\", \"bcde\", \"cdef\"\n" + }, + "empty_bytes_copy.sol": { + "content": "contract C {\n bytes data;\n bytes otherData;\n function fromMemory() public returns (bytes1) {\n bytes memory t;\n uint[2] memory x;\n x[0] = type(uint).max;\n data = t;\n data.push();\n return data[0];\n }\n function fromCalldata(bytes calldata x) public returns (bytes1) {\n data = x;\n data.push();\n return data[0];\n }\n function fromStorage() public returns (bytes1) {\n // zero-length but dirty higher order bits\n assembly { sstore(otherData.slot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00) }\n data = otherData;\n data.push();\n return data[0];\n }\n}\n// ----\n// fromMemory() -> 0x00\n// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// fromStorage() -> 0x00\n" + }, + "nested_array_element_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] memory _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] memory _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] memory _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] memory _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] memory _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] memory _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_dyn_2d_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function f(bytes[] calldata c) external returns (bytes[] memory) {\n return c;\n }\n}\n// ----\n// f(bytes[]): 0x20, 2, 0x60, 0x60, 0x20, 2, \"ab\" -> 0x20, 2, 0x40, 0x80, 2, \"ab\", 2, \"ab\"\n" + }, + "bytes_inside_mappings.sol": { + "content": "contract c {\n function set(uint key) public returns (bool) { data[key] = msg.data; return true; }\n function copy(uint from, uint to) public returns (bool) { data[to] = data[from]; return true; }\n mapping(uint => bytes) data;\n}\n// ----\n// set(uint256): 1, 2 -> true\n// gas irOptimized: 110550\n// gas legacy: 111310\n// gas legacyOptimized: 110741\n// set(uint256): 2, 2, 3, 4, 5 -> true\n// gas irOptimized: 177501\n// gas legacy: 178312\n// gas legacyOptimized: 177716\n// storageEmpty -> 0\n// copy(uint256,uint256): 1, 2 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 1 -> true\n// storageEmpty -> 0\n// copy(uint256,uint256): 99, 2 -> true\n// storageEmpty -> 1\n" + }, + "arrays_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[] public data;\n function set(uint24[] memory _data) public returns (uint) {\n data = _data;\n return data.length;\n }\n function get() public returns (uint24[] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18\n// gas irOptimized: 99616\n// gas legacy: 103509\n// gas legacyOptimized: 101266\n// data(uint256): 7 -> 8\n// data(uint256): 15 -> 16\n// data(uint256): 18 -> FAILURE\n// get() -> 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\n" + }, + "array_of_structs_containing_arrays_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n S[] s;\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n// gas irOptimized: 327456\n" + }, + "nested_array_of_structs_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n function test1(S[1][2] memory a) public returns (S[1][2] memory r) {\n r = a;\n }\n\n function test2(S[1][] memory a) public returns (S[1][] memory r) {\n r = a;\n }\n\n function test3(S[][2] memory a) public returns (S[][2] memory r) {\n r = a;\n }\n}\n// ----\n// test1((uint8,uint8)[1][2]): 1, 2, 3, 4 -> 1, 2, 3, 4\n// test2((uint8,uint8)[1][]): 0x20, 3, 7, 11, 13, 17, 19, 23 -> 0x20, 3, 7, 11, 13, 17, 19, 23\n// test3((uint8,uint8)[][2]): 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19 -> 0x20, 0x40, 0xa0, 1, 3, 7, 2, 11, 13, 17, 19\n" + }, + "nested_array_of_structs_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n S[][] s1;\n S[][1] s2;\n S[1][] s3;\n\n function test1(S[][] calldata _a) public returns (S[][] memory){\n s1 = _a;\n return s1;\n }\n\n function test2(S[][1] calldata _a) public returns (S[][1] memory) {\n s2 = _a;\n return s2;\n }\n\n function test3(S[1][] calldata _a) public returns (S[1][] memory) {\n s3 = _a;\n return s3;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1((uint8[],uint8[2])[][]): 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29 -> 0x20, 2, 0x40, 0x0140, 1, 0x20, 0x60, 3, 7, 2, 1, 2, 2, 0x40, 0x0100, 0x60, 17, 19, 2, 11, 13, 0x60, 31, 37, 2, 23, 29\n// gas irOptimized: 304788\n// test2((uint8[],uint8[2])[][1]): 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 0x20, 1, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 116653\n// test3((uint8[],uint8[2])[1][]): 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13 -> 0x20, 2, 0x40, 0x0120, 0x20, 0x60, 3, 7, 2, 1, 2, 0x20, 0x60, 17, 19, 2, 11, 13\n// gas irOptimized: 187994\n" + }, + "calldata_bytes_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bytes[] calldata a)\n external\n returns (uint256, uint256, bytes memory)\n {\n bytes memory m = a[0];\n return (a.length, m.length, m);\n }\n}\n// ----\n// f(bytes[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 0x1, 0x2, 0x60, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\" -> 0x1, 0x20, 0x60, 0x20, hex\"7878787878787878787878787878787878787878787878787878787878787878\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\" -> 0x1, 0x20, 0x60, 0x20, hex\"7800000000000000000000000000000000000000000000000000000000000061\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\" -> 0x1, 0x20, 0x60, 0x20, hex\"6100000000000000000000000000000000000000000000000000000000000078\"\n// f(bytes[]): 0x20, 0x1, 0x20, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\" -> 0x1, 0x20, 0x60, 0x20, hex\"616d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d6d78\"\n" + }, + "nested_array_of_structs_with_nested_array_from_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[] a;\n uint8[2] b;\n }\n\n uint8[] a1;\n uint8[] a2;\n uint8[] a3;\n\n S[][] s1;\n S[1][1] s2;\n\n constructor() {\n a1.push(23);\n a1.push(29);\n a2.push(31);\n\n s1 = new S[][](2);\n s1[0] = new S[](2);\n s1[0][0] = S({a: a1, b: [7, 11]});\n s1[0][1] = S({a: a2, b: [17, 19]});\n\n s1[1] = new S[](1);\n s1[1][0] = S({a: a3, b: [37, 41]});\n\n s2[0][0] = S({a: a3, b: [43, 47]});\n }\n\n function test1() public returns (S[] memory) {\n return s1[0];\n }\n\n function test2() public returns (S[1] memory) {\n return s2[0];\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1() -> 0x20, 2, 0x40, 0x0100, 0x60, 7, 11, 2, 23, 29, 0x60, 17, 19, 1, 31\n// test2() -> 0x20, 0x20, 0x60, 43, 47, 0\n" + }, + "array_of_structs_containing_arrays_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256[] a;\n }\n\n function f(S[] calldata c) external returns (uint256, uint256) {\n S[] memory s = c;\n assert(s.length == c.length);\n for (uint i = 0; i < s.length; i++) {\n assert(s[i].a.length == c[i].a.length);\n for (uint j = 0; j < s[i].a.length; j++) {\n assert(s[i].a[j] == c[i].a[j]);\n }\n }\n return (s[1].a.length, s[1].a[0]);\n }\n}\n// ----\n// f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1\n" + }, + "array_copy_storage_storage_static_simple.sol": { + "content": "contract C {\n bytes1[2] data1;\n bytes2[2] data2;\n function test() public returns (bytes2, bytes2) {\n uint i;\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n return (data2[0], data2[1]);\n }\n}\n// ----\n// test() -> left(0x01), left(0x02)\n// gas legacy: 90001\n// gas legacyOptimized: 89085\n" + }, + "array_copy_clear_storage.sol": { + "content": "contract C {\n uint256[] x;\n function f() public returns(uint256) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint256[] memory y = new uint256[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n assert(x[1] == 0);\n assert(x[2] == 0);\n return x[3];\n }\n}\n// ----\n// f() -> 0\n// gas irOptimized: 108229\n// gas legacy: 108216\n// gas legacyOptimized: 107625\n" + }, + "array_nested_memory_to_storage.sol": { + "content": "contract Test {\n uint128[13] unused;\n uint256[][] a;\n uint256[4][] b;\n uint256[2][3] c;\n\n function test() external returns (uint256) {\n uint256[][] memory m = new uint256[][](2);\n m[0] = new uint256[](3);\n m[0][0] = 7; m[0][1] = 8; m[0][2] = 9;\n m[1] = new uint256[](4);\n m[1][1] = 7; m[1][2] = 8; m[1][3] = 9;\n a = m;\n return a[0][0] + a[0][1] + a[1][3];\n }\n\n function test1() external returns (uint256) {\n uint256[2][] memory m = new uint256[2][](1);\n m[0][0] = 1; m[0][1] = 2;\n b = m;\n return b[0][0] + b[0][1];\n }\n\n function test2() external returns (uint256) {\n uint256[2][2] memory m;\n m[0][0] = 1; m[1][1] = 2; m[0][1] = 3;\n c = m;\n return c[0][0] + c[1][1] + c[0][1];\n }\n\n function test3() external returns (uint256) {\n uint256[2][3] memory m;\n m[0][0] = 7; m[1][0] = 8; m[2][0] = 9;\n m[0][1] = 7; m[1][1] = 8; m[2][1] = 9;\n a = m;\n return a[0][0] + a[1][0] + a[2][1];\n }\n}\n// ----\n// test() -> 24\n// gas irOptimized: 226734\n// gas legacy: 227083\n// gas legacyOptimized: 226529\n// test1() -> 3\n// test2() -> 6\n// test3() -> 24\n// gas irOptimized: 141319\n// gas legacy: 142238\n// gas legacyOptimized: 141365\n" + }, + "storage_memory_packed_dyn.sol": { + "content": "contract C {\n uint8[] a;\n\n function f() public returns (uint8, uint8, uint8) {\n for (uint i = 0; i < 33; i++)\n a.push(7);\n a[0] = 2;\n a[16] = 3;\n a[32] = 4;\n uint8[] memory m = a;\n return (m[0], m[16], m[32]);\n }\n}\n// ----\n// f() -> 2, 3, 4\n// gas irOptimized: 114338\n// gas legacy: 122231\n// gas legacyOptimized: 118409\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata.sol b/examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata.sol new file mode 100644 index 00000000..dec1a2d1 --- /dev/null +++ b/examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata.sol @@ -0,0 +1,7 @@ +contract C { + function f(string calldata s) public returns (bytes calldata m) { + return bytes(s); + } +} +// ---- +// f(string): 0x20, 3, "abc" -> 0x20, 3, "abc" diff --git a/examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata_standard_input.json b/examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata_standard_input.json new file mode 100644 index 00000000..c86ccbbc --- /dev/null +++ b/examples/test/semanticTests/array_copying_string_calldata_to_bytes_calldata/string_calldata_to_bytes_calldata_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "array_copy_cleanup_uint128.sol": { + "content": "// Test to see if cleanup is performed properly during array copying\ncontract C {\n uint128[] x;\n function f() public returns(bool) {\n x.push(42); x.push(42); x.push(42); x.push(42);\n uint128[] memory y = new uint128[](1);\n y[0] = 23;\n x = y;\n assembly { sstore(x.slot, 4) }\n\n assert(x[0] == 23);\n assert(x[1] == 0);\n\n assert(x[2] == 0);\n // Issue 9832: the cleanup was only performed for the first packed type leaving the rest of\n // the slot dirty.\n assert(x[3] == 0);\n\n return true;\n }\n}\n// ----\n// f() -> true\n// gas irOptimized: 92740\n// gas legacy: 93035\n// gas legacyOptimized: 92257\n" + }, + "array_of_function_external_storage_to_storage_dynamic.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public {}\n function testFunction3() public {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n function copyExternalStorageArrayOfFunctionType() external returns (bool) {\n assert(keccak256(abi.encode(externalArray0)) != keccak256(abi.encode(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encode(externalArray0)) == keccak256(abi.encode(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool) {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArrayOfFunctionType() -> true\n// gas irOptimized: 104566\n// gas legacy: 108554\n// gas legacyOptimized: 102405\n// copyInternalArrayOfFunctionType() -> true\n" + }, + "nested_array_element_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function test1(uint8[][][] calldata _a) public returns (uint8[][] memory) {\n return _a[1];\n }\n\n function test2(uint8[][1][] calldata _a) public returns (uint8[][1] memory) {\n return _a[0];\n }\n\n function test3(uint8[2][][2] calldata _a) public returns (uint8[2][] memory) {\n return _a[0];\n }\n\n function test4(uint16[][] calldata _a) public returns (uint16[][] memory) {\n uint16[][][] memory tmp = new uint16[][][](2);\n tmp[1] = _a;\n return tmp[1];\n }\n\n function test5(uint32[][2] calldata _a) public returns (uint32[][2] memory) {\n uint32[][2][] memory tmp = new uint32[][2][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n\n function test6(uint32[2][] calldata _a) public returns (uint32[2][] memory) {\n uint32[2][][] memory tmp = new uint32[2][][](1);\n tmp[0] = _a;\n return tmp[0];\n }\n}\n// ----\n// test1(uint8[][][]): 0x20, 2, 0x40, 0x60, 0, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test2(uint8[][1][]): 0x20, 2, 0x40, 0xe0, 0x20, 3, 12, 13, 14, 0x20, 3, 15, 16, 17 -> 0x20, 0x20, 3, 12, 13, 14\n// test3(uint8[2][][2]): 0x20, 0x40, 0xa0, 1, 7, 7, 2, 8, 8, 0x09, 9 -> 0x20, 1, 7, 7\n// test4(uint16[][]): 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 2, 0x40, 0x80, 1, 7, 2, 8, 9\n// test5(uint32[][2]): 0x20, 0x40, 0x80, 1, 7, 2, 8, 9 -> 0x20, 0x40, 0x80, 1, 7, 2, 8, 9\n// test6(uint32[2][]): 0x20, 2, 5, 6, 7, 8 -> 0x20, 2, 5, 6, 7, 8\n" + }, + "calldata_array_of_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n S[] memory m = s;\n l = m.length;\n a = m[0].a;\n b = m[0].b;\n c = m[1].a;\n d = m[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "calldata_2d_bytes_to_memory_2.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(bytes[2] memory m) internal {\n assert(m[0].length > 1);\n assert(m[1].length > 1);\n assert(m[0][0] == m[1][0]);\n assert(m[0][1] == m[1][1]);\n }\n function f(bytes[2] calldata c) external {\n g(c);\n }\n}\n// ----\n// f(bytes[2]): 0x20, 0x40, 0x40, 2, \"ab\" ->\n// f(bytes[2]): 0x20, 0x40, 0x40, 1, \"a\" -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "memory_dyn_2d_bytes_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n bytes[] s;\n function f() external returns (uint256) {\n bytes[] memory m = new bytes[](3);\n m[0] = \"ab\"; m[1] = \"cde\"; m[2] = \"fghij\";\n s = m;\n assert(s.length == m.length);\n for (uint i = 0; i < s.length; ++i) {\n assert(s[i].length == m[i].length);\n for (uint j = 0; j < s[i].length; ++j) {\n assert(s[i][j] == m[i][j]);\n }\n }\n return s.length;\n }\n}\n// ----\n// f() -> 3\n// gas irOptimized: 128296\n// gas legacy: 129077\n// gas legacyOptimized: 128210\n" + }, + "array_copy_storage_abi_signed.sol": { + "content": "// NOTE: This does not really test copying from storage to ABI directly,\n// because it will always copy to memory first.\ncontract c {\n int16[] x;\n\n function test() public returns (int16[] memory) {\n x.push(int16(-1));\n x.push(int16(-1));\n x.push(int16(8));\n x.push(int16(-16));\n x.push(int16(-2));\n x.push(int16(6));\n x.push(int16(8));\n x.push(int16(-1));\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x8, -1, -1, 8, -16, -2, 6, 8, -1\n" + }, + "storage_memory_nested_from_pointer.sol": { + "content": "contract C {\n uint72[5][] a;\n\n function f() public returns (uint72, uint72, uint72, uint72, uint72, uint72, uint72) {\n for (uint i = 0; i < 4; i++)\n a.push();\n a[0][0] = 1;\n a[0][3] = 2;\n a[1][1] = 3;\n a[1][4] = 4;\n a[2][0] = 5;\n a[3][2] = 6;\n a[3][3] = 7;\n uint72[5][] storage a_ = a;\n uint72[5][] memory m = a_;\n return (m[0][0], m[0][3], m[1][1], m[1][4], m[2][0], m[3][2], m[3][3]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5, 6, 7\n// gas irOptimized: 206440\n// gas legacy: 211770\n// gas legacyOptimized: 211191\n" + }, + "array_copy_target_leftover.sol": { + "content": "contract c {\n bytes1[10] data1;\n bytes2[32] data2;\n function test() public returns (uint check, uint res1, uint res2) {\n uint i;\n for (i = 0; i < data2.length; ++i)\n data2[i] = 0xffff;\n check = uint(uint16(data2[31])) * 0x10000 | uint(uint16(data2[14]));\n for (i = 0; i < data1.length; ++i)\n data1[i] = bytes1(uint8(1 + i));\n data2 = data1;\n for (i = 0; i < 16; ++i)\n res1 |= uint(uint16(data2[i])) * 0x10000**i;\n for (i = 0; i < 16; ++i)\n res2 |= uint(uint16(data2[16 + i])) * 0x10000**i;\n }\n}\n// ----\n// test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 100496\n// gas legacy: 158109\n// gas legacyOptimized: 141019\n" + }, + "array_copy_including_array.sol": { + "content": "contract c {\n uint[3][90][] large;\n uint[3][3][] small;\n function test() public returns (uint r) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n large[3][2][0] = 2;\n large[1] = large[3];\n small[3][2][0] = 2;\n small[1] = small[2];\n r = ((\n small[3][2][0] * 0x100 |\n small[1][2][0]) * 0x100 |\n large[3][2][0]) * 0x100 |\n large[1][2][0];\n delete small;\n delete large;\n\n }\n function clear() public returns (uint, uint) {\n for (uint i = 0; i < 7; i++) {\n large.push();\n small.push();\n }\n small[3][2][0] = 0;\n large[3][2][0] = 0;\n while (small.length > 0)\n small.pop();\n while (large.length > 0)\n large.pop();\n return (small.length, large.length);\n }\n}\n// ----\n// test() -> 0x02000202\n// gas irOptimized: 4549676\n// gas legacy: 4475394\n// gas legacyOptimized: 4447665\n// storageEmpty -> 1\n// clear() -> 0, 0\n// gas irOptimized: 4478184\n// gas legacy: 4407185\n// gas legacyOptimized: 4381337\n// storageEmpty -> 1\n" + }, + "array_nested_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint256[][] a1;\n uint256[][2] a2;\n uint256[2][] a3;\n uint256[2][2] a4;\n\n constructor() {\n a1 = new uint256[][](2);\n a1[0] = [1, 2];\n a1[1] = [3, 4, 5];\n\n a2[0] = [6, 7, 8];\n a2[1] = [9];\n\n a3.push([1, 2]);\n a3.push([3, 4]);\n a3.push([5, 6]);\n\n a4 = [[10, 11], [12, 13]];\n }\n\n function test1() external returns (uint256[][] memory) {\n return a1;\n }\n\n function test2() external returns (uint256[][2] memory) {\n return a2;\n }\n\n function test3() external returns (uint256[2][] memory) {\n return a3;\n }\n\n function test4() external returns (uint256[2][2] memory) {\n return a4;\n }\n}\n// ----\n// test1() -> 0x20, 2, 0x40, 0xa0, 2, 1, 2, 3, 3, 4, 5\n// test2() -> 0x20, 0x40, 0xc0, 3, 6, 7, 8, 1, 9\n// test3() -> 0x20, 3, 1, 2, 3, 4, 5, 6\n// test4() -> 10, 11, 12, 13\n" + }, + "nested_array_element_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n uint8[][][] src1 = new uint8[][][](2);\n uint8[][][2] src2;\n uint8[][2][] src3 = new uint8[][2][](1);\n uint8[2][][] src4 = new uint8[2][][](2);\n\n uint8[][] dst1;\n uint8[][] dst2;\n uint8[][2] dst3;\n uint8[][] dst4;\n\n constructor() {\n src1[1] = new uint8[][](2);\n src1[1][0] = [3, 4];\n src1[1][1] = [5, 6];\n\n src2[0] = new uint8[][](2);\n src2[0][0] = [6, 7];\n src2[0][1] = [8, 9];\n src2[1] = new uint8[][](2);\n src2[1][0] = [10, 11];\n\n src3[0][0] = [3, 4];\n src3[0][1] = [5, 6];\n\n src4[0] = new uint8[2][](1);\n src4[0][0] = [17, 23];\n src4[1] = new uint8[2][](1);\n src4[1][0] = [19, 31];\n }\n\n function test1() public {\n dst1 = src1[1];\n\n require(dst1.length == 2);\n require(dst1[0][0] == src1[1][0][0]);\n require(dst1[0][1] == src1[1][0][1]);\n require(dst1[1][0] == src1[1][1][0]);\n require(dst1[1][1] == src1[1][1][1]);\n }\n\n function test2() public {\n dst2 = src2[0];\n\n require(dst2.length == 2);\n require(dst2[0][0] == src2[1][0][0]);\n require(dst2[0][1] == src2[1][0][1]);\n require(dst2[1][0] == src2[1][1][0]);\n require(dst2[1][1] == src2[1][1][1]);\n }\n\n function test3() public {\n dst3 = src3[0];\n require(dst3[0][0] == src3[0][0][0]);\n require(dst3[0][1] == src3[0][0][1]);\n require(dst3[1][0] == src3[0][1][0]);\n require(dst3[1][1] == src3[0][1][1]);\n }\n\n function test4() public {\n dst4 = src4[1];\n require(dst4.length == 2);\n require(dst4[0][0] == src4[0][0][0]);\n require(dst4[0][1] == src4[0][0][1]);\n require(dst4[1][0] == src4[0][1][0]);\n require(dst4[1][1] == src4[0][1][1]);\n }\n}\n// ----\n// test1() ->\n// gas irOptimized: 150488\n// gas legacy: 150949\n// gas legacyOptimized: 150906\n// test2() -> FAILURE\n// gas irOptimized: 150389\n// gas legacy: 150672\n// gas legacyOptimized: 150575\n// test3() ->\n// gas irOptimized: 124300\n// gas legacy: 125333\n// gas legacyOptimized: 125127\n// test4() -> FAILURE\n" + }, + "bytes_storage_to_storage.sol": { + "content": "contract c {\n bytes a;\n bytes b;\n function f(uint len) public returns (bytes memory) {\n bytes memory x = new bytes(len);\n for (uint i = 0; i < len; i++)\n x[i] = bytes1(uint8(i));\n a = x;\n for (uint i = 0; i < len; i++)\n assert(a[i] == x[i]);\n b = a;\n for (uint i = 0; i < len; i++)\n assert(b[i] == x[i]);\n return b;\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x00\n// f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00\n// gas irOptimized: 103268\n// gas legacy: 112904\n// gas legacyOptimized: 112647\n// f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671\n// gas irOptimized: 117825\n// gas legacy: 128964\n// gas legacyOptimized: 128854\n// f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 124091\n// gas legacy: 136092\n// gas legacyOptimized: 135469\n// f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992\n// gas irOptimized: 127151\n// gas legacy: 148692\n// gas legacyOptimized: 148699\n// f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000\n// gas legacy: 59345\n// gas legacyOptimized: 57279\n// f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// gas irOptimized: 416918\n// gas legacy: 458997\n// gas legacyOptimized: 460664\n" + }, + "copy_internal_function_array_to_storage.sol": { + "content": "contract C {\n function() internal returns (uint)[20] x;\n int256 mutex;\n\n function one() public returns (uint256) {\n function() internal returns (uint)[20] memory xmem;\n x = xmem;\n return 3;\n }\n\n function two() public returns (uint256) {\n if (mutex > 0) return 7;\n mutex = 1;\n // If this test fails, it might re-execute this function.\n x[0]();\n return 2;\n }\n}\n// ----\n// one() -> 3\n// gas legacy: 140253\n// gas legacyOptimized: 140093\n// two() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "array_of_function_external_storage_to_storage_dynamic_different_mutability.sol": { + "content": "contract C {\n function testFunction1() public {}\n function testFunction2() public view {}\n function testFunction3() public pure {}\n\n\n function() external [] externalArray0;\n function() external [] externalArray1;\n\n function() internal [] internalArray0;\n function() internal [] internalArray1;\n\n constructor() {\n externalArray0 = new function() external[] (3);\n externalArray1 = [\n this.testFunction1,\n this.testFunction2,\n this.testFunction3\n ];\n\n internalArray0 = new function() internal[] (3);\n internalArray1 = [\n testFunction1,\n testFunction2,\n testFunction3\n ];\n }\n\n\n function copyExternalStorageArraysOfFunctionType() external returns (bool)\n {\n assert(keccak256(abi.encodePacked(externalArray0)) != keccak256(abi.encodePacked(externalArray1)));\n externalArray0 = externalArray1;\n return keccak256(abi.encodePacked(externalArray0)) == keccak256(abi.encodePacked(externalArray1));\n }\n\n function copyInternalArrayOfFunctionType() external returns (bool)\n {\n internalArray0 = internalArray1;\n assert(internalArray0.length == 3);\n\n return\n internalArray0.length == internalArray1.length &&\n internalArray0[0] == internalArray1[0] &&\n internalArray0[1] == internalArray1[1] &&\n internalArray0[2] == internalArray1[2];\n }\n}\n// ----\n// copyExternalStorageArraysOfFunctionType() -> true\n// gas irOptimized: 104238\n// gas legacy: 108295\n// gas legacyOptimized: 102162\n// copyInternalArrayOfFunctionType() -> true\n// gas legacy: 104178\n" + }, + "nested_array_of_structs_storage_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n uint8 y;\n }\n\n S[][] src1;\n S[][1] src2;\n S[1][] src3;\n\n S[][] dst1;\n S[][1] dst2;\n S[1][] dst3;\n\n constructor() {\n src1 = new S[][](1);\n src1[0].push(S({x: 3, y: 7}));\n src1[0].push(S({x: 11, y: 13}));\n\n src2[0].push(S({x: 3, y: 7}));\n src2[0].push(S({x: 11, y: 13}));\n src2[0].push(S({x: 17, y: 19}));\n\n src3.push([S({x: 3, y: 7})]);\n src3.push([S({x: 11, y: 13})]);\n }\n\n function test1() public {\n dst1 = src1;\n\n require(dst1.length == 1);\n require(dst1[0][0].x == src1[0][0].x);\n require(dst1[0][0].y == src1[0][0].y);\n require(dst1[0][1].x == src1[0][1].x);\n require(dst1[0][1].y == src1[0][1].y);\n }\n\n function test2() public {\n dst2 = src2;\n\n require(dst2[0].length == 3);\n require(dst2[0][0].x == src2[0][0].x);\n require(dst2[0][0].y == src2[0][0].y);\n require(dst2[0][1].x == src2[0][1].x);\n require(dst2[0][1].y == src2[0][1].y);\n require(dst2[0][2].x == src2[0][2].x);\n require(dst2[0][2].y == src2[0][2].y);\n }\n\n function test3() public {\n dst3 = src3;\n\n require(dst3.length == 2);\n require(dst3[0][0].x == src3[0][0].x);\n require(dst3[0][0].y == src3[0][0].y);\n require(dst3[1][0].x == src3[1][0].x);\n require(dst3[1][0].y == src3[1][0].y);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test1()\n// gas irOptimized: 123195\n// test2()\n// gas irOptimized: 123018\n// test3()\n" + }, + "string_calldata_to_bytes_calldata.sol": { + "content": "contract C {\n function f(string calldata s) public returns (bytes calldata m) {\n return bytes(s);\n }\n}\n// ----\n// f(string): 0x20, 3, \"abc\" -> 0x20, 3, \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length.sol b/examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length.sol new file mode 100644 index 00000000..9d2dbd8c --- /dev/null +++ b/examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length.sol @@ -0,0 +1,8 @@ +contract C { + function f() public returns (uint256) { + uint256[][] memory a = new uint256[][](0); + return 7; + } +} +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length_standard_input.json b/examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length_standard_input.json new file mode 100644 index 00000000..c33ee19a --- /dev/null +++ b/examples/test/semanticTests/array_create_dynamic_array_with_zero_length/create_dynamic_array_with_zero_length_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_create_memory_array/create_memory_array.sol b/examples/test/semanticTests/array_create_memory_array/create_memory_array.sol new file mode 100644 index 00000000..00f32a6e --- /dev/null +++ b/examples/test/semanticTests/array_create_memory_array/create_memory_array.sol @@ -0,0 +1,23 @@ +contract C { + struct S { + uint256[2] a; + bytes b; + } + + function f() public returns (bytes1, uint256, uint256, bytes1) { + bytes memory x = new bytes(200); + x[199] = "A"; + uint256[2][] memory y = new uint256[2][](300); + y[203][1] = 8; + S[] memory z = new S[](180); + z[170].a[1] = 4; + z[170].b = new bytes(102); + z[170].b[99] = "B"; + return (x[199], y[203][1], z[170].a[1], z[170].b[99]); + } +} +// ---- +// f() -> "A", 8, 4, "B" +// gas irOptimized: 136664 +// gas legacy: 121380 +// gas legacyOptimized: 115488 diff --git a/examples/test/semanticTests/array_create_memory_array/create_memory_array_standard_input.json b/examples/test/semanticTests/array_create_memory_array/create_memory_array_standard_input.json new file mode 100644 index 00000000..d6f6e550 --- /dev/null +++ b/examples/test/semanticTests/array_create_memory_array/create_memory_array_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large.sol b/examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large.sol new file mode 100644 index 00000000..1d886a8c --- /dev/null +++ b/examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large.sol @@ -0,0 +1,24 @@ +contract C { + function f() public returns (uint256) { + uint256 l = 2**256 / 32; + // This used to work without causing an error. + uint256[] memory x = new uint256[](l); + uint256[] memory y = new uint256[](1); + x[1] = 42; + // This used to overwrite the value written above. + y[0] = 23; + return x[1]; + } + function g() public returns (uint256) { + uint256 l = 2**256 / 2 + 1; + // This used to work without causing an error. + uint16[] memory x = new uint16[](l); + uint16[] memory y = new uint16[](1); + x[2] = 42; + // This used to overwrite the value written above. + y[0] = 23; + return x[2]; + }} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x41 +// g() -> FAILURE, hex"4e487b71", 0x41 diff --git a/examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large_standard_input.json b/examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large_standard_input.json new file mode 100644 index 00000000..9aced5a8 --- /dev/null +++ b/examples/test/semanticTests/array_create_memory_array_too_large/create_memory_array_too_large_standard_input.json @@ -0,0 +1,217 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array.sol b/examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array.sol new file mode 100644 index 00000000..b4c29d0f --- /dev/null +++ b/examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (bytes1) { + bytes memory x = new bytes(35); + assert(x.length == 35); + x[34] = "A"; + return (x[34]); + } +} +// ---- +// f() -> "A" diff --git a/examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array_standard_input.json b/examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array_standard_input.json new file mode 100644 index 00000000..ea24d456 --- /dev/null +++ b/examples/test/semanticTests/array_create_memory_byte_array/create_memory_byte_array_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays.sol b/examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays.sol new file mode 100644 index 00000000..2396e317 --- /dev/null +++ b/examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays.sol @@ -0,0 +1,33 @@ +contract C { + function f() public returns (uint256) { + uint256[][] memory x = new uint256[][](42); + assert(x[0].length == 0); + x[0] = new uint256[](1); + x[0][0] = 1; + assert(x[4].length == 0); + x[4] = new uint256[](1); + x[4][0] = 2; + assert(x[10].length == 0); + x[10] = new uint256[](1); + x[10][0] = 44; + uint256[][] memory y = new uint256[][](24); + assert(y[0].length == 0); + y[0] = new uint256[](1); + y[0][0] = 1; + assert(y[4].length == 0); + y[4] = new uint256[](1); + y[4][0] = 2; + assert(y[10].length == 0); + y[10] = new uint256[](1); + y[10][0] = 88; + if ( + (x[0][0] == y[0][0]) && + (x[4][0] == y[4][0]) && + (x[10][0] == 44) && + (y[10][0] == 88) + ) return 7; + return 0; + } +} +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays_standard_input.json b/examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays_standard_input.json new file mode 100644 index 00000000..bccbc2b9 --- /dev/null +++ b/examples/test/semanticTests/array_create_multiple_dynamic_arrays/create_multiple_dynamic_arrays_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element.sol b/examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element.sol new file mode 100644 index 00000000..f776626a --- /dev/null +++ b/examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element.sol @@ -0,0 +1,21 @@ +contract c { + bytes data; + + function test1() external returns (bool) { + data = new bytes(100); + for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i)); + delete data[94]; + delete data[96]; + delete data[98]; + return + data[94] == 0 && + uint8(data[95]) == 95 && + data[96] == 0 && + uint8(data[97]) == 97; + } +} +// ---- +// test1() -> true +// gas irOptimized: 218449 +// gas legacy: 242263 +// gas legacyOptimized: 241182 diff --git a/examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element_standard_input.json b/examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element_standard_input.json new file mode 100644 index 00000000..abd5db1b --- /dev/null +++ b/examples/test/semanticTests/array_delete_bytes_delete_element/bytes_delete_element_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + }, + "delete_storage_array_packed.sol": { + "content": "contract C {\n uint120[] data;\n\n function f() public returns (uint120, uint120, uint120) {\n data.push(123);\n data.push(234);\n data.push(345);\n delete data;\n assembly {\n sstore(data.slot, 3)\n }\n return (data[0], data[1], data[2]);\n }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 90992\n// gas legacy: 111037\n// gas legacyOptimized: 109633\n" + }, + "delete_storage_array.sol": { + "content": "contract C {\n uint[] data;\n\n function len() public returns (uint ret) {\n data.push(234);\n data.push(123);\n delete data;\n assembly {\n ret := sload(data.slot)\n }\n }\n\n function val() public returns (uint ret) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n sstore(add(keccak256(0, 32), 1), 123)\n }\n\n assert(data[0] == 234);\n assert(data[1] == 123);\n\n delete data;\n\n uint size = 999;\n\n assembly {\n size := sload(0)\n mstore(0, 0)\n ret := sload(keccak256(0, 32))\n }\n }\n}\n// ----\n// len() -> 0\n// val() -> 0\n" + }, + "bytes_delete_element.sol": { + "content": "contract c {\n bytes data;\n\n function test1() external returns (bool) {\n data = new bytes(100);\n for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i));\n delete data[94];\n delete data[96];\n delete data[98];\n return\n data[94] == 0 &&\n uint8(data[95]) == 95 &&\n data[96] == 0 &&\n uint8(data[97]) == 97;\n }\n}\n// ----\n// test1() -> true\n// gas irOptimized: 218449\n// gas legacy: 242263\n// gas legacyOptimized: 241182\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array.sol b/examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array.sol new file mode 100644 index 00000000..b735d182 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array.sol @@ -0,0 +1,34 @@ +contract C { + bytes data; + + function f() public returns (uint ret) { + data.push("a"); + data.push("b"); + delete data; + assembly { + ret := sload(data.slot) + } + } + + function g() public returns (uint ret) { + assembly { + sstore(data.slot, 67) + } + data.push("a"); + data.push("b"); + assert(data.length == 35); + delete data; + assert(data.length == 0); + + uint size = 999; + assembly { + size := sload(data.slot) + mstore(0, data.slot) + ret := sload(keccak256(0, 32)) + } + assert(size == 0); + } +} +// ---- +// f() -> 0 +// g() -> 0 diff --git a/examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array_standard_input.json b/examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array_standard_input.json new file mode 100644 index 00000000..fdae94e6 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_bytes_array/delete_bytes_array_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + }, + "delete_storage_array_packed.sol": { + "content": "contract C {\n uint120[] data;\n\n function f() public returns (uint120, uint120, uint120) {\n data.push(123);\n data.push(234);\n data.push(345);\n delete data;\n assembly {\n sstore(data.slot, 3)\n }\n return (data[0], data[1], data[2]);\n }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 90992\n// gas legacy: 111037\n// gas legacyOptimized: 109633\n" + }, + "delete_storage_array.sol": { + "content": "contract C {\n uint[] data;\n\n function len() public returns (uint ret) {\n data.push(234);\n data.push(123);\n delete data;\n assembly {\n ret := sload(data.slot)\n }\n }\n\n function val() public returns (uint ret) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n sstore(add(keccak256(0, 32), 1), 123)\n }\n\n assert(data[0] == 234);\n assert(data[1] == 123);\n\n delete data;\n\n uint size = 999;\n\n assembly {\n size := sload(0)\n mstore(0, 0)\n ret := sload(keccak256(0, 32))\n }\n }\n}\n// ----\n// len() -> 0\n// val() -> 0\n" + }, + "bytes_delete_element.sol": { + "content": "contract c {\n bytes data;\n\n function test1() external returns (bool) {\n data = new bytes(100);\n for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i));\n delete data[94];\n delete data[96];\n delete data[98];\n return\n data[94] == 0 &&\n uint8(data[95]) == 95 &&\n data[96] == 0 &&\n uint8(data[97]) == 97;\n }\n}\n// ----\n// test1() -> true\n// gas irOptimized: 218449\n// gas legacy: 242263\n// gas legacyOptimized: 241182\n" + }, + "delete_memory_array.sol": { + "content": "contract C {\n\n function len() public returns (uint ret) {\n uint[] memory data = new uint[](2);\n data[0] = 234;\n data[1] = 123;\n delete data;\n assembly {\n ret := mload(data)\n }\n }\n}\n// ----\n// len() -> 0\n" + }, + "delete_on_array_of_structs.sol": { + "content": "// Test for a bug where we did not increment the counter properly while deleting a dynamic array.\ncontract C {\n struct S {\n uint256 x;\n uint256[] y;\n }\n S[] data;\n\n function f() public returns (bool) {\n S storage s1 = data.push();\n s1.x = 2**200;\n S storage s2 = data.push();\n s2.x = 2**200;\n delete data;\n return true;\n }\n}\n// ----\n// f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access #\n" + }, + "delete_bytes_array.sol": { + "content": "contract C {\n bytes data;\n\n function f() public returns (uint ret) {\n data.push(\"a\");\n data.push(\"b\");\n delete data;\n assembly {\n ret := sload(data.slot)\n }\n }\n\n function g() public returns (uint ret) {\n assembly {\n sstore(data.slot, 67)\n }\n data.push(\"a\");\n data.push(\"b\");\n assert(data.length == 35);\n delete data;\n assert(data.length == 0);\n\n uint size = 999;\n assembly {\n size := sload(data.slot)\n mstore(0, data.slot)\n ret := sload(keccak256(0, 32))\n }\n assert(size == 0);\n }\n}\n// ----\n// f() -> 0\n// g() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array.sol b/examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array.sol new file mode 100644 index 00000000..53a66af3 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array.sol @@ -0,0 +1,14 @@ +contract C { + + function len() public returns (uint ret) { + uint[] memory data = new uint[](2); + data[0] = 234; + data[1] = 123; + delete data; + assembly { + ret := mload(data) + } + } +} +// ---- +// len() -> 0 diff --git a/examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array_standard_input.json b/examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array_standard_input.json new file mode 100644 index 00000000..887bb553 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_memory_array/delete_memory_array_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + }, + "delete_storage_array_packed.sol": { + "content": "contract C {\n uint120[] data;\n\n function f() public returns (uint120, uint120, uint120) {\n data.push(123);\n data.push(234);\n data.push(345);\n delete data;\n assembly {\n sstore(data.slot, 3)\n }\n return (data[0], data[1], data[2]);\n }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 90992\n// gas legacy: 111037\n// gas legacyOptimized: 109633\n" + }, + "delete_storage_array.sol": { + "content": "contract C {\n uint[] data;\n\n function len() public returns (uint ret) {\n data.push(234);\n data.push(123);\n delete data;\n assembly {\n ret := sload(data.slot)\n }\n }\n\n function val() public returns (uint ret) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n sstore(add(keccak256(0, 32), 1), 123)\n }\n\n assert(data[0] == 234);\n assert(data[1] == 123);\n\n delete data;\n\n uint size = 999;\n\n assembly {\n size := sload(0)\n mstore(0, 0)\n ret := sload(keccak256(0, 32))\n }\n }\n}\n// ----\n// len() -> 0\n// val() -> 0\n" + }, + "bytes_delete_element.sol": { + "content": "contract c {\n bytes data;\n\n function test1() external returns (bool) {\n data = new bytes(100);\n for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i));\n delete data[94];\n delete data[96];\n delete data[98];\n return\n data[94] == 0 &&\n uint8(data[95]) == 95 &&\n data[96] == 0 &&\n uint8(data[97]) == 97;\n }\n}\n// ----\n// test1() -> true\n// gas irOptimized: 218449\n// gas legacy: 242263\n// gas legacyOptimized: 241182\n" + }, + "delete_memory_array.sol": { + "content": "contract C {\n\n function len() public returns (uint ret) {\n uint[] memory data = new uint[](2);\n data[0] = 234;\n data[1] = 123;\n delete data;\n assembly {\n ret := mload(data)\n }\n }\n}\n// ----\n// len() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs.sol b/examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs.sol new file mode 100644 index 00000000..2c1421ee --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs.sol @@ -0,0 +1,19 @@ +// Test for a bug where we did not increment the counter properly while deleting a dynamic array. +contract C { + struct S { + uint256 x; + uint256[] y; + } + S[] data; + + function f() public returns (bool) { + S storage s1 = data.push(); + s1.x = 2**200; + S storage s2 = data.push(); + s2.x = 2**200; + delete data; + return true; + } +} +// ---- +// f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access # diff --git a/examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs_standard_input.json b/examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs_standard_input.json new file mode 100644 index 00000000..3e6d6117 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_on_array_of_structs/delete_on_array_of_structs_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + }, + "delete_storage_array_packed.sol": { + "content": "contract C {\n uint120[] data;\n\n function f() public returns (uint120, uint120, uint120) {\n data.push(123);\n data.push(234);\n data.push(345);\n delete data;\n assembly {\n sstore(data.slot, 3)\n }\n return (data[0], data[1], data[2]);\n }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 90992\n// gas legacy: 111037\n// gas legacyOptimized: 109633\n" + }, + "delete_storage_array.sol": { + "content": "contract C {\n uint[] data;\n\n function len() public returns (uint ret) {\n data.push(234);\n data.push(123);\n delete data;\n assembly {\n ret := sload(data.slot)\n }\n }\n\n function val() public returns (uint ret) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n sstore(add(keccak256(0, 32), 1), 123)\n }\n\n assert(data[0] == 234);\n assert(data[1] == 123);\n\n delete data;\n\n uint size = 999;\n\n assembly {\n size := sload(0)\n mstore(0, 0)\n ret := sload(keccak256(0, 32))\n }\n }\n}\n// ----\n// len() -> 0\n// val() -> 0\n" + }, + "bytes_delete_element.sol": { + "content": "contract c {\n bytes data;\n\n function test1() external returns (bool) {\n data = new bytes(100);\n for (uint256 i = 0; i < data.length; i++) data[i] = bytes1(uint8(i));\n delete data[94];\n delete data[96];\n delete data[98];\n return\n data[94] == 0 &&\n uint8(data[95]) == 95 &&\n data[96] == 0 &&\n uint8(data[97]) == 97;\n }\n}\n// ----\n// test1() -> true\n// gas irOptimized: 218449\n// gas legacy: 242263\n// gas legacyOptimized: 241182\n" + }, + "delete_memory_array.sol": { + "content": "contract C {\n\n function len() public returns (uint ret) {\n uint[] memory data = new uint[](2);\n data[0] = 234;\n data[1] = 123;\n delete data;\n assembly {\n ret := mload(data)\n }\n }\n}\n// ----\n// len() -> 0\n" + }, + "delete_on_array_of_structs.sol": { + "content": "// Test for a bug where we did not increment the counter properly while deleting a dynamic array.\ncontract C {\n struct S {\n uint256 x;\n uint256[] y;\n }\n S[] data;\n\n function f() public returns (bool) {\n S storage s1 = data.push();\n s1.x = 2**200;\n S storage s2 = data.push();\n s2.x = 2**200;\n delete data;\n return true;\n }\n}\n// ----\n// f() -> true # This code interprets x as an array length and thus will go out of gas. neither of the two should throw due to out-of-bounds access #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data.sol b/examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data.sol new file mode 100644 index 00000000..c407eb73 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data.sol @@ -0,0 +1,10 @@ +contract c { + fallback() external { data = msg.data; } + function del() public returns (bool) { delete data; return true; } + bytes data; +} +// ---- +// (): 7 -> +// storageEmpty -> 0 +// del(): 7 -> true +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data_standard_input.json b/examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data_standard_input.json new file mode 100644 index 00000000..4876e09e --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_removes_bytes_data/delete_removes_bytes_data_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array.sol b/examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array.sol new file mode 100644 index 00000000..41364566 --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array.sol @@ -0,0 +1,37 @@ +contract C { + uint[] data; + + function len() public returns (uint ret) { + data.push(234); + data.push(123); + delete data; + assembly { + ret := sload(data.slot) + } + } + + function val() public returns (uint ret) { + assembly { + sstore(0, 2) + mstore(0, 0) + sstore(keccak256(0, 32), 234) + sstore(add(keccak256(0, 32), 1), 123) + } + + assert(data[0] == 234); + assert(data[1] == 123); + + delete data; + + uint size = 999; + + assembly { + size := sload(0) + mstore(0, 0) + ret := sload(keccak256(0, 32)) + } + } +} +// ---- +// len() -> 0 +// val() -> 0 diff --git a/examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array_standard_input.json b/examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array_standard_input.json new file mode 100644 index 00000000..26cf8d3a --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_storage_array/delete_storage_array_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + }, + "delete_storage_array_packed.sol": { + "content": "contract C {\n uint120[] data;\n\n function f() public returns (uint120, uint120, uint120) {\n data.push(123);\n data.push(234);\n data.push(345);\n delete data;\n assembly {\n sstore(data.slot, 3)\n }\n return (data[0], data[1], data[2]);\n }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 90992\n// gas legacy: 111037\n// gas legacyOptimized: 109633\n" + }, + "delete_storage_array.sol": { + "content": "contract C {\n uint[] data;\n\n function len() public returns (uint ret) {\n data.push(234);\n data.push(123);\n delete data;\n assembly {\n ret := sload(data.slot)\n }\n }\n\n function val() public returns (uint ret) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n sstore(add(keccak256(0, 32), 1), 123)\n }\n\n assert(data[0] == 234);\n assert(data[1] == 123);\n\n delete data;\n\n uint size = 999;\n\n assembly {\n size := sload(0)\n mstore(0, 0)\n ret := sload(keccak256(0, 32))\n }\n }\n}\n// ----\n// len() -> 0\n// val() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed.sol b/examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed.sol new file mode 100644 index 00000000..9665201c --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed.sol @@ -0,0 +1,19 @@ +contract C { + uint120[] data; + + function f() public returns (uint120, uint120, uint120) { + data.push(123); + data.push(234); + data.push(345); + delete data; + assembly { + sstore(data.slot, 3) + } + return (data[0], data[1], data[2]); + } +} +// ---- +// f() -> 0, 0, 0 +// gas irOptimized: 90992 +// gas legacy: 111037 +// gas legacyOptimized: 109633 diff --git a/examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed_standard_input.json b/examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed_standard_input.json new file mode 100644 index 00000000..8261efbe --- /dev/null +++ b/examples/test/semanticTests/array_delete_delete_storage_array_packed/delete_storage_array_packed_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + }, + "delete_removes_bytes_data.sol": { + "content": "contract c {\n fallback() external { data = msg.data; }\n function del() public returns (bool) { delete data; return true; }\n bytes data;\n}\n// ----\n// (): 7 ->\n// storageEmpty -> 0\n// del(): 7 -> true\n// storageEmpty -> 1\n" + }, + "delete_storage_array_packed.sol": { + "content": "contract C {\n uint120[] data;\n\n function f() public returns (uint120, uint120, uint120) {\n data.push(123);\n data.push(234);\n data.push(345);\n delete data;\n assembly {\n sstore(data.slot, 3)\n }\n return (data[0], data[1], data[2]);\n }\n}\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 90992\n// gas legacy: 111037\n// gas legacyOptimized: 109633\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete.sol b/examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete.sol new file mode 100644 index 00000000..732e90ad --- /dev/null +++ b/examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete.sol @@ -0,0 +1,13 @@ +contract Test { + function del() public returns (uint24[3][4] memory) { + uint24[3][4] memory x; + for (uint24 i = 0; i < x.length; i ++) + for (uint24 j = 0; j < x[i].length; j ++) + x[i][j] = i * 0x10 + j; + delete x[1]; + delete x[3][2]; + return x; + } +} +// ---- +// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0 diff --git a/examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete_standard_input.json b/examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete_standard_input.json new file mode 100644 index 00000000..7963fb68 --- /dev/null +++ b/examples/test/semanticTests/array_delete_memory_arrays_delete/memory_arrays_delete_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "memory_arrays_delete.sol": { + "content": "contract Test {\n function del() public returns (uint24[3][4] memory) {\n uint24[3][4] memory x;\n for (uint24 i = 0; i < x.length; i ++)\n for (uint24 j = 0; j < x[i].length; j ++)\n x[i][j] = i * 0x10 + j;\n delete x[1];\n delete x[3][2];\n return x;\n }\n}\n// ----\n// del() -> 0, 1, 2, 0, 0, 0, 0x20, 0x21, 0x22, 0x30, 0x31, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup.sol b/examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup.sol new file mode 100644 index 00000000..b2be566a --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup.sol @@ -0,0 +1,27 @@ +contract c { + uint[20] spacer; + uint[] dynamic; + function fill() public { + for (uint i = 0; i < 21; ++i) + dynamic.push(i + 1); + } + function halfClear() public { + while (dynamic.length > 5) + dynamic.pop(); + } + function fullClear() public { delete dynamic; } +} +// ---- +// storageEmpty -> 1 +// fill() -> +// gas irOptimized: 519494 +// gas legacy: 518943 +// gas legacyOptimized: 515555 +// storageEmpty -> 0 +// halfClear() -> +// gas irOptimized: 113961 +// gas legacy: 113257 +// gas legacyOptimized: 113120 +// storageEmpty -> 0 +// fullClear() -> +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup_standard_input.json b/examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup_standard_input.json new file mode 100644 index 00000000..3fe316a7 --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_array_cleanup/dynamic_array_cleanup_standard_input.json @@ -0,0 +1,196 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage.sol b/examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage.sol new file mode 100644 index 00000000..f9647373 --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage.sol @@ -0,0 +1,55 @@ +contract c { + struct Data { + uint256 x; + uint256 y; + } + Data[] data; + uint256[] ids; + + function setIDStatic(uint256 id) public { + ids[2] = id; + } + + function setID(uint256 index, uint256 id) public { + ids[index] = id; + } + + function setData(uint256 index, uint256 x, uint256 y) public { + data[index].x = x; + data[index].y = y; + } + + function getID(uint256 index) public returns (uint256) { + return ids[index]; + } + + function getData(uint256 index) public returns (uint256 x, uint256 y) { + x = data[index].x; + y = data[index].y; + } + + function getLengths() public returns (uint256 l1, uint256 l2) { + l1 = data.length; + l2 = ids.length; + } + + function setLengths(uint256 l1, uint256 l2) public { + while (data.length < l1) data.push(); + while (ids.length < l2) ids.push(); + } +} +// ---- +// getLengths() -> 0, 0 +// setLengths(uint256,uint256): 48, 49 -> +// gas irOptimized: 112674 +// gas legacy: 108272 +// gas legacyOptimized: 100268 +// getLengths() -> 48, 49 +// setIDStatic(uint256): 11 -> +// getID(uint256): 2 -> 11 +// setID(uint256,uint256): 7, 8 -> +// getID(uint256): 7 -> 8 +// setData(uint256,uint256,uint256): 7, 8, 9 -> +// setData(uint256,uint256,uint256): 8, 10, 11 -> +// getData(uint256): 7 -> 8, 9 +// getData(uint256): 8 -> 10, 11 diff --git a/examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage_standard_input.json b/examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage_standard_input.json new file mode 100644 index 00000000..c8569c27 --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_arrays_in_storage/dynamic_arrays_in_storage_standard_input.json @@ -0,0 +1,214 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup.sol b/examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup.sol new file mode 100644 index 00000000..2db14a93 --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup.sol @@ -0,0 +1,24 @@ +contract c { + struct s { uint[][] d; } + s[] data; + function fill() public returns (uint) { + while (data.length < 3) + data.push(); + while (data[2].d.length < 4) + data[2].d.push(); + while (data[2].d[3].length < 5) + data[2].d[3].push(); + data[2].d[3][4] = 8; + return data[2].d[3][4]; + } + function clear() public { delete data; } +} +// ---- +// storageEmpty -> 1 +// fill() -> 8 +// gas irOptimized: 122985 +// gas legacy: 121602 +// gas legacyOptimized: 120589 +// storageEmpty -> 0 +// clear() -> +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup_standard_input.json b/examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup_standard_input.json new file mode 100644 index 00000000..c9759b17 --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_multi_array_cleanup/dynamic_multi_array_cleanup_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access.sol b/examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access.sol new file mode 100644 index 00000000..5cf35ef3 --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access.sol @@ -0,0 +1,31 @@ +contract c { + uint256[] data; + + function enlarge(uint256 amount) public returns (uint256) { + while (data.length < amount) data.push(); + return data.length; + } + + function set(uint256 index, uint256 value) public returns (bool) { + data[index] = value; + return true; + } + + function get(uint256 index) public returns (uint256) { + return data[index]; + } + + function length() public returns (uint256) { + return data.length; + } +} +// ---- +// length() -> 0 +// get(uint256): 3 -> FAILURE, hex"4e487b71", 0x32 +// enlarge(uint256): 4 -> 4 +// length() -> 4 +// set(uint256,uint256): 3, 4 -> true +// get(uint256): 3 -> 4 +// length() -> 4 +// set(uint256,uint256): 4, 8 -> FAILURE, hex"4e487b71", 0x32 +// length() -> 4 diff --git a/examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access_standard_input.json b/examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access_standard_input.json new file mode 100644 index 00000000..f1fa366c --- /dev/null +++ b/examples/test/semanticTests/array_dynamic_out_of_bounds_array_access/dynamic_out_of_bounds_array_access_standard_input.json @@ -0,0 +1,211 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access.sol b/examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access.sol new file mode 100644 index 00000000..f09757c6 --- /dev/null +++ b/examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access.sol @@ -0,0 +1,18 @@ +contract A { + uint256[3] arr; + bool public test = false; + + function getElement(uint256 i) public returns (uint256) { + return arr[i]; + } + + function testIt() public returns (bool) { + uint256 i = this.getElement(5); + test = true; + return true; + } +} +// ---- +// test() -> false +// testIt() -> FAILURE, hex"4e487b71", 0x32 +// test() -> false diff --git a/examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access_standard_input.json b/examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access_standard_input.json new file mode 100644 index 00000000..858c4ce2 --- /dev/null +++ b/examples/test/semanticTests/array_evm_exceptions_out_of_band_access/evm_exceptions_out_of_band_access_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_external_array_args/external_array_args.sol b/examples/test/semanticTests/array_external_array_args/external_array_args.sol new file mode 100644 index 00000000..da6664f9 --- /dev/null +++ b/examples/test/semanticTests/array_external_array_args/external_array_args.sol @@ -0,0 +1,10 @@ +contract c { + function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index) + external returns (uint av, uint bv, uint cv) { + av = a[a_index]; + bv = b[b_index]; + cv = c[c_index]; + } +} +// ---- +// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23 diff --git a/examples/test/semanticTests/array_external_array_args/external_array_args_standard_input.json b/examples/test/semanticTests/array_external_array_args/external_array_args_standard_input.json new file mode 100644 index 00000000..6b3cef6d --- /dev/null +++ b/examples/test/semanticTests/array_external_array_args/external_array_args_standard_input.json @@ -0,0 +1,202 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup.sol b/examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup.sol new file mode 100644 index 00000000..ebe2186f --- /dev/null +++ b/examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup.sol @@ -0,0 +1,21 @@ +contract c { + uint spacer1; + uint spacer2; + uint[20] data; + function fill() public { + for (uint i = 0; i < data.length; ++i) data[i] = i+1; + } + function clear() public { delete data; } +} +// ---- +// storageEmpty -> 1 +// fill() -> +// gas irOptimized: 465013 +// gas legacy: 468825 +// gas legacyOptimized: 466238 +// storageEmpty -> 0 +// clear() -> +// gas irOptimized: 122148 +// gas legacy: 122440 +// gas legacyOptimized: 122259 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup_standard_input.json b/examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup_standard_input.json new file mode 100644 index 00000000..d461314e --- /dev/null +++ b/examples/test/semanticTests/array_fixed_array_cleanup/fixed_array_cleanup_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type.sol b/examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type.sol new file mode 100644 index 00000000..e4bf3a71 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type.sol @@ -0,0 +1,26 @@ +contract A { + function f(uint16 input) public pure returns (uint16[5] memory arr) { + arr[0] = input; + arr[1] = ++input; + arr[2] = ++input; + arr[3] = ++input; + arr[4] = ++input; + } +} + + +contract B { + function f() public returns (uint16[5] memory res, uint16[5] memory res2) { + A a = new A(); + res = a.f(2); + res2 = a.f(1000); + } +} +// ---- +// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 +// gas irOptimized: 59212 +// gas irOptimized code: 56600 +// gas legacy: 68001 +// gas legacy code: 162000 +// gas legacyOptimized: 59997 +// gas legacyOptimized code: 70600 diff --git a/examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type_standard_input.json b/examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type_standard_input.json new file mode 100644 index 00000000..938cb1d0 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_arrays_as_return_type/fixed_arrays_as_return_type_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors.sol b/examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors.sol new file mode 100644 index 00000000..8e9780e3 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors.sol @@ -0,0 +1,19 @@ +contract Creator { + uint256 public r; + address public ch; + + constructor(address[3] memory s, uint256 x) { + r = x; + ch = s[2]; + } +} +// ---- +// constructor(): 1, 2, 3, 4 -> +// gas irOptimized: 104102 +// gas irOptimized code: 22400 +// gas legacy: 115185 +// gas legacy code: 59000 +// gas legacyOptimized: 104908 +// gas legacyOptimized code: 23800 +// r() -> 4 +// ch() -> 3 diff --git a/examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors_standard_input.json b/examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors_standard_input.json new file mode 100644 index 00000000..170d25bc --- /dev/null +++ b/examples/test/semanticTests/array_fixed_arrays_in_constructors/fixed_arrays_in_constructors_standard_input.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage.sol b/examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage.sol new file mode 100644 index 00000000..b65a3d25 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage.sol @@ -0,0 +1,45 @@ +contract c { + struct Data { + uint256 x; + uint256 y; + } + Data[2**10] data; + uint256[2**10 + 3] ids; + + function setIDStatic(uint256 id) public { + ids[2] = id; + } + + function setID(uint256 index, uint256 id) public { + ids[index] = id; + } + + function setData(uint256 index, uint256 x, uint256 y) public { + data[index].x = x; + data[index].y = y; + } + + function getID(uint256 index) public returns (uint256) { + return ids[index]; + } + + function getData(uint256 index) public returns (uint256 x, uint256 y) { + x = data[index].x; + y = data[index].y; + } + + function getLengths() public returns (uint256 l1, uint256 l2) { + l1 = data.length; + l2 = ids.length; + } +} +// ---- +// setIDStatic(uint256): 0xb -> +// getID(uint256): 0x2 -> 0xb +// setID(uint256,uint256): 0x7, 0x8 -> +// getID(uint256): 0x7 -> 0x8 +// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 -> +// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb -> +// getData(uint256): 0x7 -> 0x8, 0x9 +// getData(uint256): 0x8 -> 0xa, 0xb +// getLengths() -> 0x400, 0x403 diff --git a/examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage_standard_input.json b/examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage_standard_input.json new file mode 100644 index 00000000..19ce7b98 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_arrays_in_storage/fixed_arrays_in_storage_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access.sol b/examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access.sol new file mode 100644 index 00000000..d641cd83 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access.sol @@ -0,0 +1,9 @@ +contract C { + bytes1 a; + + function f(bytes32 x) public returns (uint256, uint256, uint256) { + return (x.length, bytes16(uint128(2)).length, a.length + 7); + } +} +// ---- +// f(bytes32): "789" -> 32, 16, 8 diff --git a/examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access_standard_input.json b/examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access_standard_input.json new file mode 100644 index 00000000..2213a39d --- /dev/null +++ b/examples/test/semanticTests/array_fixed_bytes_length_access/fixed_bytes_length_access_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access.sol b/examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access.sol new file mode 100644 index 00000000..1b3b6408 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access.sol @@ -0,0 +1,25 @@ +contract c { + uint256[4] data; + + function set(uint256 index, uint256 value) public returns (bool) { + data[index] = value; + return true; + } + + function get(uint256 index) public returns (uint256) { + return data[index]; + } + + function length() public returns (uint256) { + return data.length; + } +} +// ---- +// length() -> 4 +// set(uint256,uint256): 3, 4 -> true +// set(uint256,uint256): 4, 5 -> FAILURE, hex"4e487b71", 0x32 +// set(uint256,uint256): 400, 5 -> FAILURE, hex"4e487b71", 0x32 +// get(uint256): 3 -> 4 +// get(uint256): 4 -> FAILURE, hex"4e487b71", 0x32 +// get(uint256): 400 -> FAILURE, hex"4e487b71", 0x32 +// length() -> 4 diff --git a/examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access_standard_input.json b/examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access_standard_input.json new file mode 100644 index 00000000..82f53362 --- /dev/null +++ b/examples/test/semanticTests/array_fixed_out_of_bounds_array_access/fixed_out_of_bounds_array_access_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls.sol b/examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls.sol new file mode 100644 index 00000000..f3dea83b --- /dev/null +++ b/examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls.sol @@ -0,0 +1,50 @@ +contract D { + function f(function() external returns (function() external returns (uint))[] memory x) + public returns (function() external returns (uint)[3] memory r) { + r[0] = x[0](); + r[1] = x[1](); + r[2] = x[2](); + } +} + + +contract C { + function test() public returns (uint256, uint256, uint256) { + function() external returns (function() external returns (uint))[] memory x = + new function() external returns (function() external returns (uint))[](10); + for (uint256 i = 0; i < x.length; i++) x[i] = this.h; + x[0] = this.htwo; + function() external returns (uint)[3] memory y = (new D()).f(x); + return (y[0](), y[1](), y[2]()); + } + + function e() public returns (uint256) { + return 5; + } + + function f() public returns (uint256) { + return 6; + } + + function g() public returns (uint256) { + return 7; + } + + uint256 counter; + + function h() public returns (function() external returns (uint)) { + return counter++ == 0 ? this.f : this.g; + } + + function htwo() public returns (function() external returns (uint)) { + return this.e; + } +} +// ---- +// test() -> 5, 6, 7 +// gas irOptimized: 86484 +// gas irOptimized code: 161200 +// gas legacy: 97551 +// gas legacy code: 342800 +// gas legacyOptimized: 87808 +// gas legacyOptimized code: 193000 diff --git a/examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls_standard_input.json b/examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls_standard_input.json new file mode 100644 index 00000000..55585e5d --- /dev/null +++ b/examples/test/semanticTests/array_function_array_cross_calls/function_array_cross_calls_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_function_memory_array/function_memory_array.sol b/examples/test/semanticTests/array_function_memory_array/function_memory_array.sol new file mode 100644 index 00000000..bdd23c67 --- /dev/null +++ b/examples/test/semanticTests/array_function_memory_array/function_memory_array.sol @@ -0,0 +1,39 @@ +contract C { + function a(uint256 x) public returns (uint256) { + return x + 1; + } + + function b(uint256 x) public returns (uint256) { + return x + 2; + } + + function c(uint256 x) public returns (uint256) { + return x + 3; + } + + function d(uint256 x) public returns (uint256) { + return x + 5; + } + + function e(uint256 x) public returns (uint256) { + return x + 8; + } + + function test(uint256 x, uint256 i) public returns (uint256) { + function(uint) internal returns (uint)[] memory arr = + new function(uint) internal returns (uint)[](10); + arr[0] = a; + arr[1] = b; + arr[2] = c; + arr[3] = d; + arr[4] = e; + return arr[i](x); + } +} +// ---- +// test(uint256,uint256): 10, 0 -> 11 +// test(uint256,uint256): 10, 1 -> 12 +// test(uint256,uint256): 10, 2 -> 13 +// test(uint256,uint256): 10, 3 -> 15 +// test(uint256,uint256): 10, 4 -> 18 +// test(uint256,uint256): 10, 5 -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/array_function_memory_array/function_memory_array_standard_input.json b/examples/test/semanticTests/array_function_memory_array/function_memory_array_standard_input.json new file mode 100644 index 00000000..ed52bfcc --- /dev/null +++ b/examples/test/semanticTests/array_function_memory_array/function_memory_array_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access.sol b/examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access.sol new file mode 100644 index 00000000..79d8f202 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access.sol @@ -0,0 +1,11 @@ +contract Test { + function set(uint24[3][] memory _data, uint256 a, uint256 b) + public + returns (uint256 l, uint256 e) + { + l = _data.length; + e = _data[a][b]; + } +} +// ---- +// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c diff --git a/examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access_standard_input.json b/examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access_standard_input.json new file mode 100644 index 00000000..fd46b4dc --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_arrays_complex_memory_index_access/arrays_complex_memory_index_access_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access.sol b/examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access.sol new file mode 100644 index 00000000..0e9168bc --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access.sol @@ -0,0 +1,25 @@ +contract c { + bytes data; + function direct(bytes calldata arg, uint index) external returns (uint) { + return uint(uint8(arg[index])); + } + function storageCopyRead(bytes calldata arg, uint index) external returns (uint) { + data = arg; + return uint(uint8(data[index])); + } + function storageWrite() external returns (uint) { + data = new bytes(35); + data[31] = 0x77; + data[32] = 0x14; + + data[31] = 0x01; + data[31] |= 0x08; + data[30] = 0x01; + data[32] = 0x03; + return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32])); + } +} +// ---- +// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21 +// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21 +// storageWrite() -> 0x193 diff --git a/examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access_standard_input.json b/examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access_standard_input.json new file mode 100644 index 00000000..18d3cf84 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_bytes_index_access/bytes_index_access_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "index_access.sol": { + "content": "contract C {\n function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n" + }, + "inline_array_index_access_strings.sol": { + "content": "contract C {\n string public tester;\n\n function f() public returns (string memory) {\n return ([\"abc\", \"def\", \"g\"][0]);\n }\n\n function test() public {\n tester = f();\n }\n}\n// ----\n// test() ->\n// tester() -> 0x20, 0x3, \"abc\"\n" + }, + "memory_arrays_index_access_write.sol": { + "content": "contract Test {\n function set(uint24[3][4] memory x) public {\n x[2][2] = 1;\n x[3][2] = 7;\n }\n\n function f() public returns (uint24[3][4] memory) {\n uint24[3][4] memory data;\n set(data);\n return data;\n }\n}\n// ----\n// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "bytes_index_access.sol": { + "content": "contract c {\n bytes data;\n function direct(bytes calldata arg, uint index) external returns (uint) {\n return uint(uint8(arg[index]));\n }\n function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {\n data = arg;\n return uint(uint8(data[index]));\n }\n function storageWrite() external returns (uint) {\n data = new bytes(35);\n data[31] = 0x77;\n data[32] = 0x14;\n\n data[31] = 0x01;\n data[31] |= 0x08;\n data[30] = 0x01;\n data[32] = 0x03;\n return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));\n }\n}\n// ----\n// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageWrite() -> 0x193\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory.sol b/examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory.sol new file mode 100644 index 00000000..fa65d25c --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory.sol @@ -0,0 +1,15 @@ +contract Main { + function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) { + c1 = _s1[i1]; + c2 = intern(_s1, i2); + c3 = internIndirect(_s1)[i3]; + } + function intern(bytes memory _s1, uint i) public returns (bytes1 c) { + return _s1[i]; + } + function internIndirect(bytes memory _s1) public returns (bytes memory) { + return _s1; + } +} +// ---- +// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> "d", "e", "f" diff --git a/examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory_standard_input.json b/examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory_standard_input.json new file mode 100644 index 00000000..d3fcb487 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_bytes_index_access_memory/bytes_index_access_memory_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access.sol b/examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access.sol new file mode 100644 index 00000000..6dd62499 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access.sol @@ -0,0 +1,11 @@ +contract Test { + function set(bytes memory _data, uint256 i) + public + returns (uint256 l, bytes1 c) + { + l = _data.length; + c = _data[i]; + } +} +// ---- +// set(bytes,uint256): 0x40, 0x03, 0x08, "abcdefgh" -> 0x08, "d" diff --git a/examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access_standard_input.json b/examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access_standard_input.json new file mode 100644 index 00000000..674f32ba --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_bytes_memory_index_access/bytes_memory_index_access_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "index_access.sol": { + "content": "contract C {\n function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n" + }, + "inline_array_index_access_strings.sol": { + "content": "contract C {\n string public tester;\n\n function f() public returns (string memory) {\n return ([\"abc\", \"def\", \"g\"][0]);\n }\n\n function test() public {\n tester = f();\n }\n}\n// ----\n// test() ->\n// tester() -> 0x20, 0x3, \"abc\"\n" + }, + "memory_arrays_index_access_write.sol": { + "content": "contract Test {\n function set(uint24[3][4] memory x) public {\n x[2][2] = 1;\n x[3][2] = 7;\n }\n\n function f() public returns (uint24[3][4] memory) {\n uint24[3][4] memory data;\n set(data);\n return data;\n }\n}\n// ----\n// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "bytes_index_access.sol": { + "content": "contract c {\n bytes data;\n function direct(bytes calldata arg, uint index) external returns (uint) {\n return uint(uint8(arg[index]));\n }\n function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {\n data = arg;\n return uint(uint8(data[index]));\n }\n function storageWrite() external returns (uint) {\n data = new bytes(35);\n data[31] = 0x77;\n data[32] = 0x14;\n\n data[31] = 0x01;\n data[31] |= 0x08;\n data[30] = 0x01;\n data[32] = 0x03;\n return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));\n }\n}\n// ----\n// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageWrite() -> 0x193\n" + }, + "bytes_memory_index_access.sol": { + "content": "contract Test {\n function set(bytes memory _data, uint256 i)\n public\n returns (uint256 l, bytes1 c)\n {\n l = _data.length;\n c = _data[i];\n }\n}\n// ----\n// set(bytes,uint256): 0x40, 0x03, 0x08, \"abcdefgh\" -> 0x08, \"d\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access.sol b/examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access.sol new file mode 100644 index 00000000..9ab74eaf --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access.sol @@ -0,0 +1,17 @@ +contract C { + bytes16[] public data; + + function f(bytes32 x) public returns (bytes1) { + return x[2]; + } + + function g(bytes32 x) public returns (uint256) { + data = [x[0], x[1], x[2]]; + data[0] = "12345"; + return uint256(uint8(data[0][4])); + } +} +// ---- +// f(bytes32): "789" -> "9" +// g(bytes32): "789" -> 0x35 +// data(uint256): 0x01 -> "8" diff --git a/examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access_standard_input.json b/examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access_standard_input.json new file mode 100644 index 00000000..f75c8154 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_fixed_bytes_index_access/fixed_bytes_index_access_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_index_access/index_access.sol b/examples/test/semanticTests/array_indexAccess_index_access/index_access.sol new file mode 100644 index 00000000..c618ae8e --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_index_access/index_access.sol @@ -0,0 +1,18 @@ +contract C { + function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) { + ret = new bytes(8); + bytes8 bytesValue = bytes8(value); + // Byteswapping during copying to bytes. + ret[0] = bytesValue[7]; + ret[1] = bytesValue[6]; + ret[2] = bytesValue[5]; + ret[3] = bytesValue[4]; + ret[4] = bytesValue[3]; + ret[5] = bytesValue[2]; + ret[6] = bytesValue[1]; + ret[7] = bytesValue[0]; + } +} +// ---- +// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00 +// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/array_indexAccess_index_access/index_access_standard_input.json b/examples/test/semanticTests/array_indexAccess_index_access/index_access_standard_input.json new file mode 100644 index 00000000..8db7b4a7 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_index_access/index_access_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "index_access.sol": { + "content": "contract C {\n function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints.sol b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints.sol new file mode 100644 index 00000000..0525f6f2 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (uint256) { + return ([1, 2, 3, 4][2]); + } +} +// ---- +// f() -> 3 diff --git a/examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints_standard_input.json b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints_standard_input.json new file mode 100644 index 00000000..3e25cc29 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_ints/inline_array_index_access_ints_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "index_access.sol": { + "content": "contract C {\n function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n" + }, + "inline_array_index_access_strings.sol": { + "content": "contract C {\n string public tester;\n\n function f() public returns (string memory) {\n return ([\"abc\", \"def\", \"g\"][0]);\n }\n\n function test() public {\n tester = f();\n }\n}\n// ----\n// test() ->\n// tester() -> 0x20, 0x3, \"abc\"\n" + }, + "memory_arrays_index_access_write.sol": { + "content": "contract Test {\n function set(uint24[3][4] memory x) public {\n x[2][2] = 1;\n x[3][2] = 7;\n }\n\n function f() public returns (uint24[3][4] memory) {\n uint24[3][4] memory data;\n set(data);\n return data;\n }\n}\n// ----\n// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "bytes_index_access.sol": { + "content": "contract c {\n bytes data;\n function direct(bytes calldata arg, uint index) external returns (uint) {\n return uint(uint8(arg[index]));\n }\n function storageCopyRead(bytes calldata arg, uint index) external returns (uint) {\n data = arg;\n return uint(uint8(data[index]));\n }\n function storageWrite() external returns (uint) {\n data = new bytes(35);\n data[31] = 0x77;\n data[32] = 0x14;\n\n data[31] = 0x01;\n data[31] |= 0x08;\n data[30] = 0x01;\n data[32] = 0x03;\n return uint(uint8(data[30])) * 0x100 | uint(uint8(data[31])) * 0x10 | uint(uint8(data[32]));\n }\n}\n// ----\n// direct(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageCopyRead(bytes,uint256): 0x40, 33, 34, 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F, left(0x2021) -> 0x21\n// storageWrite() -> 0x193\n" + }, + "bytes_memory_index_access.sol": { + "content": "contract Test {\n function set(bytes memory _data, uint256 i)\n public\n returns (uint256 l, bytes1 c)\n {\n l = _data.length;\n c = _data[i];\n }\n}\n// ----\n// set(bytes,uint256): 0x40, 0x03, 0x08, \"abcdefgh\" -> 0x08, \"d\"\n" + }, + "inline_array_index_access_ints.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n return ([1, 2, 3, 4][2]);\n }\n}\n// ----\n// f() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings.sol b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings.sol new file mode 100644 index 00000000..bf6c0b0e --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings.sol @@ -0,0 +1,14 @@ +contract C { + string public tester; + + function f() public returns (string memory) { + return (["abc", "def", "g"][0]); + } + + function test() public { + tester = f(); + } +} +// ---- +// test() -> +// tester() -> 0x20, 0x3, "abc" diff --git a/examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings_standard_input.json b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings_standard_input.json new file mode 100644 index 00000000..911a1600 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_inline_array_index_access_strings/inline_array_index_access_strings_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "index_access.sol": { + "content": "contract C {\n function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n" + }, + "inline_array_index_access_strings.sol": { + "content": "contract C {\n string public tester;\n\n function f() public returns (string memory) {\n return ([\"abc\", \"def\", \"g\"][0]);\n }\n\n function test() public {\n tester = f();\n }\n}\n// ----\n// test() ->\n// tester() -> 0x20, 0x3, \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write.sol b/examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write.sol new file mode 100644 index 00000000..be824b75 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write.sol @@ -0,0 +1,19 @@ +contract Test { + uint24[3][][4] data; + + function set(uint24[3][][4] memory x) + internal + returns (uint24[3][][4] memory) + { + x[1][2][2] = 1; + x[1][3][2] = 7; + return x; + } + + function f() public returns (uint24[3][] memory) { + while (data[1].length < 4) data[1].push(); + return set(data)[1]; + } +} +// ---- +// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07 diff --git a/examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write_standard_input.json b/examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write_standard_input.json new file mode 100644 index 00000000..2ceb3ffb --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_memory_arrays_dynamic_index_access_write/memory_arrays_dynamic_index_access_write_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write.sol b/examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write.sol new file mode 100644 index 00000000..7a8a1867 --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write.sol @@ -0,0 +1,14 @@ +contract Test { + function set(uint24[3][4] memory x) public { + x[2][2] = 1; + x[3][2] = 7; + } + + function f() public returns (uint24[3][4] memory) { + uint24[3][4] memory data; + set(data); + return data; + } +} +// ---- +// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07 diff --git a/examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write_standard_input.json b/examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write_standard_input.json new file mode 100644 index 00000000..43714f1c --- /dev/null +++ b/examples/test/semanticTests/array_indexAccess_memory_arrays_index_access_write/memory_arrays_index_access_write_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "fixed_bytes_index_access.sol": { + "content": "contract C {\n bytes16[] public data;\n\n function f(bytes32 x) public returns (bytes1) {\n return x[2];\n }\n\n function g(bytes32 x) public returns (uint256) {\n data = [x[0], x[1], x[2]];\n data[0] = \"12345\";\n return uint256(uint8(data[0][4]));\n }\n}\n// ----\n// f(bytes32): \"789\" -> \"9\"\n// g(bytes32): \"789\" -> 0x35\n// data(uint256): 0x01 -> \"8\"\n" + }, + "bytes_index_access_memory.sol": { + "content": "contract Main {\n function f(bytes memory _s1, uint i1, uint i2, uint i3) public returns (bytes1 c1, bytes1 c2, bytes1 c3) {\n c1 = _s1[i1];\n c2 = intern(_s1, i2);\n c3 = internIndirect(_s1)[i3];\n }\n function intern(bytes memory _s1, uint i) public returns (bytes1 c) {\n return _s1[i];\n }\n function internIndirect(bytes memory _s1) public returns (bytes memory) {\n return _s1;\n }\n}\n// ----\n// f(bytes,uint256,uint256,uint256): 0x80, 3, 4, 5, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> \"d\", \"e\", \"f\"\n" + }, + "arrays_complex_memory_index_access.sol": { + "content": "contract Test {\n function set(uint24[3][] memory _data, uint256 a, uint256 b)\n public\n returns (uint256 l, uint256 e)\n {\n l = _data.length;\n e = _data[a][b];\n }\n}\n// ----\n// set(uint24[3][],uint256,uint256): 0x60, 0x03, 0x02, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06, 0x0c\n" + }, + "memory_arrays_dynamic_index_access_write.sol": { + "content": "contract Test {\n uint24[3][][4] data;\n\n function set(uint24[3][][4] memory x)\n internal\n returns (uint24[3][][4] memory)\n {\n x[1][2][2] = 1;\n x[1][3][2] = 7;\n return x;\n }\n\n function f() public returns (uint24[3][] memory) {\n while (data[1].length < 4) data[1].push();\n return set(data)[1];\n }\n}\n// ----\n// f() -> 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + }, + "index_access.sol": { + "content": "contract C {\n function to_little_endian_64(uint64 value) public pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// to_little_endian_64(uint64): 0 -> 0x20, 8, 0x00\n// to_little_endian_64(uint64): 0x0102030405060708 -> 0x20, 8, 0x0807060504030201000000000000000000000000000000000000000000000000\n" + }, + "inline_array_index_access_strings.sol": { + "content": "contract C {\n string public tester;\n\n function f() public returns (string memory) {\n return ([\"abc\", \"def\", \"g\"][0]);\n }\n\n function test() public {\n tester = f();\n }\n}\n// ----\n// test() ->\n// tester() -> 0x20, 0x3, \"abc\"\n" + }, + "memory_arrays_index_access_write.sol": { + "content": "contract Test {\n function set(uint24[3][4] memory x) public {\n x[2][2] = 1;\n x[3][2] = 7;\n }\n\n function f() public returns (uint24[3][4] memory) {\n uint24[3][4] memory data;\n set(data);\n return data;\n }\n}\n// ----\n// f() -> 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_inline_array_return/inline_array_return.sol b/examples/test/semanticTests/array_inline_array_return/inline_array_return.sol new file mode 100644 index 00000000..25302dcb --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_return/inline_array_return.sol @@ -0,0 +1,14 @@ +contract C { + uint8[] tester; + + function f() public returns (uint8[5] memory) { + return ([1, 2, 3, 4, 5]); + } + + function test() public returns (uint8, uint8, uint8, uint8, uint8) { + tester = f(); + return (tester[0], tester[1], tester[2], tester[3], tester[4]); + } +} +// ---- +// f() -> 1, 2, 3, 4, 5 diff --git a/examples/test/semanticTests/array_inline_array_return/inline_array_return_standard_input.json b/examples/test/semanticTests/array_inline_array_return/inline_array_return_standard_input.json new file mode 100644 index 00000000..9b191771 --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_return/inline_array_return_standard_input.json @@ -0,0 +1,235 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_storage_push_pop.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > 0)\n storageArray.pop();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 106222\n// gas legacy: 105722\n// gas legacyOptimized: 103508\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_storage_to_memory_conversion_ints.sol": { + "content": "contract C {\n function f() public returns (uint256 x, uint256 y) {\n x = 3;\n y = 6;\n uint256[2] memory z = [x, y];\n return (z[0], z[1]);\n }\n}\n// ----\n// f() -> 3, 6\n" + }, + "memory.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function h(uint[4] memory n) public pure returns (uint) {\n return n[0] + n[1] + n[2] + n[3];\n }\n\n function i(uint[4] memory n) public view returns (uint) {\n return this.h(n) * 2;\n }\n}\n// ----\n// h(uint256[4]): 1, 2, 3, 4 -> 10\n// i(uint256[4]): 1, 2, 3, 4 -> 20\n" + }, + "constant_var_as_array_length.sol": { + "content": "contract C {\n uint256 constant LEN = 3;\n uint256[LEN] public a;\n\n constructor(uint256[LEN] memory _a) {\n a = _a;\n }\n}\n// ----\n// constructor(): 1, 2, 3 ->\n// gas irOptimized: 124991\n// gas irOptimized code: 14800\n// gas legacy: 134317\n// gas legacy code: 46200\n// gas legacyOptimized: 127166\n// gas legacyOptimized code: 23400\n// a(uint256): 0 -> 1\n// a(uint256): 1 -> 2\n// a(uint256): 2 -> 3\n" + }, + "inline_array_return.sol": { + "content": "contract C {\n uint8[] tester;\n\n function f() public returns (uint8[5] memory) {\n return ([1, 2, 3, 4, 5]);\n }\n\n function test() public returns (uint8, uint8, uint8, uint8, uint8) {\n tester = f();\n return (tester[0], tester[1], tester[2], tester[3], tester[4]);\n }\n}\n// ----\n// f() -> 1, 2, 3, 4, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton.sol b/examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton.sol new file mode 100644 index 00000000..b14ade6e --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton.sol @@ -0,0 +1,8 @@ +// This caused a failure since the type was not converted to its mobile type. +contract C { + function f() public returns (uint256) { + return [4][0]; + } +} +// ---- +// f() -> 4 diff --git a/examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton_standard_input.json b/examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton_standard_input.json new file mode 100644 index 00000000..c7bc938b --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_singleton/inline_array_singleton_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints.sol b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints.sol new file mode 100644 index 00000000..e145d281 --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint256 x, uint256 y) { + x = 3; + y = 6; + uint256[2] memory z = [x, y]; + return (z[0], z[1]); + } +} +// ---- +// f() -> 3, 6 diff --git a/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints_standard_input.json b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints_standard_input.json new file mode 100644 index 00000000..ebfff037 --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_ints/inline_array_storage_to_memory_conversion_ints_standard_input.json @@ -0,0 +1,226 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_storage_push_pop.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > 0)\n storageArray.pop();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 106222\n// gas legacy: 105722\n// gas legacyOptimized: 103508\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_storage_to_memory_conversion_ints.sol": { + "content": "contract C {\n function f() public returns (uint256 x, uint256 y) {\n x = 3;\n y = 6;\n uint256[2] memory z = [x, y];\n return (z[0], z[1]);\n }\n}\n// ----\n// f() -> 3, 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings.sol b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings.sol new file mode 100644 index 00000000..7dfe6e64 --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings.sol @@ -0,0 +1,11 @@ +contract C { + string s = "doh"; + + function f() public returns (string memory, string memory) { + string memory t = "ray"; + string[3] memory x = [s, t, "mi"]; + return (x[1], x[2]); + } +} +// ---- +// f() -> 0x40, 0x80, 0x3, "ray", 0x2, "mi" diff --git a/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings_standard_input.json b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings_standard_input.json new file mode 100644 index 00000000..ebae2dff --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_storage_to_memory_conversion_strings/inline_array_storage_to_memory_conversion_strings_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document.sol b/examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document.sol new file mode 100644 index 00000000..9cb16349 --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document.sol @@ -0,0 +1,11 @@ +contract C { + function f(uint256 i) public returns (string memory) { + string[4] memory x = ["This", "is", "an", "array"]; + return (x[i]); + } +} +// ---- +// f(uint256): 0 -> 0x20, 0x4, "This" +// f(uint256): 1 -> 0x20, 0x2, "is" +// f(uint256): 2 -> 0x20, 0x2, "an" +// f(uint256): 3 -> 0x20, 0x5, "array" diff --git a/examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document_standard_input.json b/examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document_standard_input.json new file mode 100644 index 00000000..c838abe4 --- /dev/null +++ b/examples/test/semanticTests/array_inline_array_strings_from_document/inline_array_strings_from_document_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array.sol b/examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array.sol new file mode 100644 index 00000000..95df74b4 --- /dev/null +++ b/examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array.sol @@ -0,0 +1,95 @@ +contract C { + bytes public x = "abc"; + bytes public y; + function invalidateXShort() public { + assembly { sstore(x.slot, 64) } + delete y; + } + function invalidateXLong() public { + assembly { sstore(x.slot, 5) } + delete y; + } + function abiEncode() public view returns (bytes memory) { return x; } + function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); } + function copyToMemory() public view returns (bytes memory m) { m = x; } + function indexAccess() public view returns (bytes1) { return x[0]; } + function assignTo() public { x = "def"; } + function assignToLong() public { x = "1234567890123456789012345678901234567"; } + function copyToStorage() public { y = x; } + function copyFromStorageShort() public { y = "abc"; x = y; } + function copyFromStorageLong() public { y = "1234567890123456789012345678901234567"; x = y; } + function arrayPop() public { x.pop(); } + function arrayPush() public { x.push("t"); } + function arrayPushEmpty() public { x.push(); } + function del() public { delete x; } +} +// ---- +// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 +// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 +// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 +// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 +// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000 +// arrayPushEmpty() +// arrayPush() +// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000 +// arrayPop() +// assignToLong() +// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 +// assignTo() +// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000 +// copyFromStorageShort() +// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 +// copyFromStorageLong() +// gas irOptimized: 121095 +// gas legacy: 121904 +// gas legacyOptimized: 121388 +// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 +// copyToStorage() +// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 +// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000 +// del() +// x() -> 0x20, 0x00 +// invalidateXLong() +// x() -> FAILURE, hex"4e487b71", 0x22 +// abiEncode() -> FAILURE, hex"4e487b71", 0x22 +// abiEncodePacked() -> FAILURE, hex"4e487b71", 0x22 +// copyToMemory() -> FAILURE, hex"4e487b71", 0x22 +// indexAccess() -> FAILURE, hex"4e487b71", 0x22 +// arrayPushEmpty() -> FAILURE, hex"4e487b71", 0x22 +// arrayPush() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// arrayPop() -> FAILURE, hex"4e487b71", 0x22 +// assignToLong() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// assignTo() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// copyFromStorageShort() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// copyFromStorageLong() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// copyToStorage() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// y() -> 0x20, 0x00 +// del() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// invalidateXShort() +// x() -> FAILURE, hex"4e487b71", 0x22 +// abiEncode() -> FAILURE, hex"4e487b71", 0x22 +// abiEncodePacked() -> FAILURE, hex"4e487b71", 0x22 +// copyToMemory() -> FAILURE, hex"4e487b71", 0x22 +// indexAccess() -> FAILURE, hex"4e487b71", 0x22 +// arrayPushEmpty() -> FAILURE, hex"4e487b71", 0x22 +// arrayPush() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// arrayPop() -> FAILURE, hex"4e487b71", 0x22 +// assignToLong() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// assignTo() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// copyFromStorageShort() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// copyFromStorageLong() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// copyToStorage() -> FAILURE, hex"4e487b71", 0x22 +// x() -> FAILURE, hex"4e487b71", 0x22 +// y() -> 0x20, 0x00 diff --git a/examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array_standard_input.json b/examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array_standard_input.json new file mode 100644 index 00000000..57b90315 --- /dev/null +++ b/examples/test/semanticTests/array_invalid_encoding_for_storage_byte_array/invalid_encoding_for_storage_byte_array_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_memory/memory.sol b/examples/test/semanticTests/array_memory/memory.sol new file mode 100644 index 00000000..88c18d49 --- /dev/null +++ b/examples/test/semanticTests/array_memory/memory.sol @@ -0,0 +1,14 @@ +pragma solidity >= 0.6.0; + +contract C { + function h(uint[4] memory n) public pure returns (uint) { + return n[0] + n[1] + n[2] + n[3]; + } + + function i(uint[4] memory n) public view returns (uint) { + return this.h(n) * 2; + } +} +// ---- +// h(uint256[4]): 1, 2, 3, 4 -> 10 +// i(uint256[4]): 1, 2, 3, 4 -> 20 diff --git a/examples/test/semanticTests/array_memory/memory_standard_input.json b/examples/test/semanticTests/array_memory/memory_standard_input.json new file mode 100644 index 00000000..5cd135de --- /dev/null +++ b/examples/test/semanticTests/array_memory/memory_standard_input.json @@ -0,0 +1,229 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + }, + "array_storage_pop_zero_length.sol": { + "content": "contract C {\n uint[] storageArray;\n function popEmpty() public {\n storageArray.pop();\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// popEmpty() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "dynamic_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[] data;\n\n function enlarge(uint256 amount) public returns (uint256) {\n while (data.length < amount) data.push();\n return data.length;\n }\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 0\n// get(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x32\n// enlarge(uint256): 4 -> 4\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// get(uint256): 3 -> 4\n// length() -> 4\n// set(uint256,uint256): 4, 8 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "dynamic_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[] data;\n uint256[] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n\n function setLengths(uint256 l1, uint256 l2) public {\n while (data.length < l1) data.push();\n while (ids.length < l2) ids.push();\n }\n}\n// ----\n// getLengths() -> 0, 0\n// setLengths(uint256,uint256): 48, 49 ->\n// gas irOptimized: 112674\n// gas legacy: 108272\n// gas legacyOptimized: 100268\n// getLengths() -> 48, 49\n// setIDStatic(uint256): 11 ->\n// getID(uint256): 2 -> 11\n// setID(uint256,uint256): 7, 8 ->\n// getID(uint256): 7 -> 8\n// setData(uint256,uint256,uint256): 7, 8, 9 ->\n// setData(uint256,uint256,uint256): 8, 10, 11 ->\n// getData(uint256): 7 -> 8, 9\n// getData(uint256): 8 -> 10, 11\n" + }, + "create_memory_array_too_large.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 l = 2**256 / 32;\n // This used to work without causing an error.\n uint256[] memory x = new uint256[](l);\n uint256[] memory y = new uint256[](1);\n x[1] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[1];\n }\n function g() public returns (uint256) {\n uint256 l = 2**256 / 2 + 1;\n // This used to work without causing an error.\n uint16[] memory x = new uint16[](l);\n uint16[] memory y = new uint16[](1);\n x[2] = 42;\n // This used to overwrite the value written above.\n y[0] = 23;\n return x[2];\n }}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x41\n// g() -> FAILURE, hex\"4e487b71\", 0x41\n" + }, + "calldata_slice_access.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256 start, uint256 end) external pure {\n x[start:end];\n }\n function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) {\n return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]);\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 ->\n// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE\n// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201\n// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202\n// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205\n// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_storage_push_pop.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > 0)\n storageArray.pop();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 0\n// set_get_length(uint256): 10 -> 0\n// set_get_length(uint256): 20 -> 0\n// gas irOptimized: 106222\n// gas legacy: 105722\n// gas legacyOptimized: 103508\n// set_get_length(uint256): 0xFF -> 0\n// gas irOptimized: 833586\n// gas legacy: 807764\n// gas legacyOptimized: 784467\n// set_get_length(uint256): 0xFFF -> 0\n// gas irOptimized: 13029438\n// gas legacy: 12608096\n// gas legacyOptimized: 12239199\n// set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_storage_to_memory_conversion_ints.sol": { + "content": "contract C {\n function f() public returns (uint256 x, uint256 y) {\n x = 3;\n y = 6;\n uint256[2] memory z = [x, y];\n return (z[0], z[1]);\n }\n}\n// ----\n// f() -> 3, 6\n" + }, + "memory.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function h(uint[4] memory n) public pure returns (uint) {\n return n[0] + n[1] + n[2] + n[3];\n }\n\n function i(uint[4] memory n) public view returns (uint) {\n return this.h(n) * 2;\n }\n}\n// ----\n// h(uint256[4]): 1, 2, 3, 4 -> 10\n// i(uint256[4]): 1, 2, 3, 4 -> 20\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes.sol b/examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes.sol new file mode 100644 index 00000000..0ce758d9 --- /dev/null +++ b/examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes.sol @@ -0,0 +1,16 @@ +// Computes binomial coefficients the chinese way +contract C { + function f(uint256 n, uint256 k) public returns (uint256) { + uint256[][] memory rows = new uint256[][](n + 1); + for (uint256 i = 1; i <= n; i++) { + rows[i] = new uint256[](i); + rows[i][0] = rows[i][rows[i].length - 1] = 1; + for (uint256 j = 1; j < i - 1; j++) + rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j]; + } + return rows[n][k - 1]; + } +} +// ---- +// f(uint256,uint256): 3, 1 -> 1 +// f(uint256,uint256): 9, 5 -> 70 diff --git a/examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes_standard_input.json b/examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes_standard_input.json new file mode 100644 index 00000000..d1bf9859 --- /dev/null +++ b/examples/test/semanticTests/array_memory_arrays_of_various_sizes/memory_arrays_of_various_sizes_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop/array_pop.sol b/examples/test/semanticTests/array_pop_array_pop/array_pop.sol new file mode 100644 index 00000000..bbb140a3 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop/array_pop.sol @@ -0,0 +1,15 @@ +contract c { + uint256[] data; + + function test() public returns (uint256 x, uint256 l) { + data.push(7); + data.push(3); + x = data.length; + data.pop(); + x = data.length; + data.pop(); + l = data.length; + } +} +// ---- +// test() -> 1, 0 diff --git a/examples/test/semanticTests/array_pop_array_pop/array_pop_standard_input.json b/examples/test/semanticTests/array_pop_array_pop/array_pop_standard_input.json new file mode 100644 index 00000000..68bc9947 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop/array_pop_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition.sol b/examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition.sol new file mode 100644 index 00000000..96fb11a2 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition.sol @@ -0,0 +1,29 @@ +contract c { + uint256 a; + uint256 b; + uint256 c; + uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + uint16[][] data; + function test() public returns (uint x, uint y, uint z) { + for (uint i = 1; i <= 48; i++) + data.push(inner); + for (uint j = 1; j <= 10; j++) + data.pop(); + x = data[data.length - 1][0]; + for (uint k = 1; k <= 10; k++) + data.pop(); + y = data[data.length - 1][1]; + for (uint l = 1; l <= 10; l++) + data.pop(); + z = data[data.length - 1][2]; + for (uint m = 1; m <= 18; m++) + data.pop(); + delete inner; + } +} +// ---- +// test() -> 1, 2, 3 +// gas irOptimized: 1828226 +// gas legacy: 1822464 +// gas legacyOptimized: 1813404 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition_standard_input.json b/examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition_standard_input.json new file mode 100644 index 00000000..ab36785a --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_array_transition/array_pop_array_transition_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception.sol b/examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception.sol new file mode 100644 index 00000000..6130130d --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception.sol @@ -0,0 +1,10 @@ +contract c { + uint256[] data; + + function test() public returns (bool) { + data.pop(); + return true; + } +} +// ---- +// test() -> FAILURE, hex"4e487b71", 0x31 diff --git a/examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception_standard_input.json b/examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception_standard_input.json new file mode 100644 index 00000000..d19c4146 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_empty_exception/array_pop_empty_exception_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_empty_exception.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated.sol b/examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated.sol new file mode 100644 index 00000000..43d7c3a9 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated.sol @@ -0,0 +1,12 @@ +// This tests that the compiler knows the correct size of the function on the stack. +contract c { + uint256[] data; + + function test() public returns (uint256 x) { + x = 2; + data.pop; + x = 3; + } +} +// ---- +// test() -> 3 diff --git a/examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated_standard_input.json b/examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated_standard_input.json new file mode 100644 index 00000000..558bd3c8 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_isolated/array_pop_isolated_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty.sol b/examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty.sol new file mode 100644 index 00000000..17890cd1 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty.sol @@ -0,0 +1,10 @@ +contract c { + uint[] data; + function test() public { + data.push(7); + data.pop(); + } +} +// ---- +// test() -> +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty_standard_input.json b/examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty_standard_input.json new file mode 100644 index 00000000..2886224f --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_storage_empty/array_pop_storage_empty_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition.sol b/examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition.sol new file mode 100644 index 00000000..0c68ab70 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition.sol @@ -0,0 +1,24 @@ +contract c { + uint16[] data; + function test() public returns (uint16 x, uint16 y, uint16 z) { + for (uint i = 1; i <= 48; i++) + data.push(uint16(i)); + for (uint j = 1; j <= 10; j++) + data.pop(); + x = data[data.length - 1]; + for (uint k = 1; k <= 10; k++) + data.pop(); + y = data[data.length - 1]; + for (uint l = 1; l <= 10; l++) + data.pop(); + z = data[data.length - 1]; + for (uint m = 1; m <= 18; m++) + data.pop(); + } +} +// ---- +// test() -> 38, 28, 18 +// gas irOptimized: 148380 +// gas legacy: 151182 +// gas legacyOptimized: 142418 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition_standard_input.json b/examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition_standard_input.json new file mode 100644 index 00000000..e6c705d7 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_uint16_transition/array_pop_uint16_transition_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition.sol b/examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition.sol new file mode 100644 index 00000000..86165dde --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition.sol @@ -0,0 +1,24 @@ +contract c { + uint256 a; + uint256 b; + uint256 c; + uint24[] data; + function test() public returns (uint24 x, uint24 y) { + for (uint i = 1; i <= 30; i++) + data.push(uint24(i)); + for (uint j = 1; j <= 10; j++) + data.pop(); + x = data[data.length - 1]; + for (uint k = 1; k <= 10; k++) + data.pop(); + y = data[data.length - 1]; + for (uint l = 1; l <= 10; l++) + data.pop(); + } +} +// ---- +// test() -> 20, 10 +// gas irOptimized: 125889 +// gas legacy: 127215 +// gas legacyOptimized: 122224 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition_standard_input.json b/examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition_standard_input.json new file mode 100644 index 00000000..6da1e2b2 --- /dev/null +++ b/examples/test/semanticTests/array_pop_array_pop_uint24_transition/array_pop_uint24_transition_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_empty_exception.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "array_pop_uint24_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint24[] data;\n function test() public returns (uint24 x, uint24 y) {\n for (uint i = 1; i <= 30; i++)\n data.push(uint24(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n }\n}\n// ----\n// test() -> 20, 10\n// gas irOptimized: 125889\n// gas legacy: 127215\n// gas legacyOptimized: 122224\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop.sol b/examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop.sol new file mode 100644 index 00000000..8f015218 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop.sol @@ -0,0 +1,16 @@ +contract c { + bytes data; + + function test() public returns (uint256 x, uint256 y, uint256 l) { + data.push(0x07); + data.push(0x03); + x = data.length; + data.pop(); + data.pop(); + data.push(0x02); + y = data.length; + l = data.length; + } +} +// ---- +// test() -> 2, 1, 1 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop_standard_input.json new file mode 100644 index 00000000..d2d961b7 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop/byte_array_pop_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long.sol b/examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long.sol new file mode 100644 index 00000000..c64d93c1 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long.sol @@ -0,0 +1,14 @@ +contract c { + bytes data; + + function test() public returns (bytes memory) { + for (uint256 i = 0; i < 33; i++) data.push(0x03); + for (uint256 j = 0; j < 4; j++) data.pop(); + return data; + } +} +// ---- +// test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 +// gas irOptimized: 109310 +// gas legacy: 101220 +// gas legacyOptimized: 123422 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long_standard_input.json new file mode 100644 index 00000000..d987d630 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_copy_long/byte_array_pop_copy_long_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_empty_exception.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "array_pop_uint24_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint24[] data;\n function test() public returns (uint24 x, uint24 y) {\n for (uint i = 1; i <= 30; i++)\n data.push(uint24(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n }\n}\n// ----\n// test() -> 20, 10\n// gas irOptimized: 125889\n// gas legacy: 127215\n// gas legacyOptimized: 122224\n// storageEmpty -> 1\n" + }, + "byte_array_pop_masking_long.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bytes memory) {\n for (uint256 i = 0; i < 34; i++) data.push(0x03);\n data.pop();\n return data;\n }\n}\n// ----\n// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 106762\n// gas legacy: 121252\n// gas legacyOptimized: 120370\n" + }, + "byte_array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n bytes data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop_empty_exception.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "byte_array_pop_copy_long.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bytes memory) {\n for (uint256 i = 0; i < 33; i++) data.push(0x03);\n for (uint256 j = 0; j < 4; j++) data.pop();\n return data;\n }\n}\n// ----\n// test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000\n// gas irOptimized: 109310\n// gas legacy: 101220\n// gas legacyOptimized: 123422\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception.sol b/examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception.sol new file mode 100644 index 00000000..d860275e --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception.sol @@ -0,0 +1,13 @@ +contract c { + uint256 a; + uint256 b; + uint256 c; + bytes data; + + function test() public returns (bool) { + data.pop(); + return true; + } +} +// ---- +// test() -> FAILURE, hex"4e487b71", 0x31 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception_standard_input.json new file mode 100644 index 00000000..e9e7078a --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_empty_exception/byte_array_pop_empty_exception_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_empty_exception.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "array_pop_uint24_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint24[] data;\n function test() public returns (uint24 x, uint24 y) {\n for (uint i = 1; i <= 30; i++)\n data.push(uint24(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n }\n}\n// ----\n// test() -> 20, 10\n// gas irOptimized: 125889\n// gas legacy: 127215\n// gas legacyOptimized: 122224\n// storageEmpty -> 1\n" + }, + "byte_array_pop_masking_long.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bytes memory) {\n for (uint256 i = 0; i < 34; i++) data.push(0x03);\n data.pop();\n return data;\n }\n}\n// ----\n// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 106762\n// gas legacy: 121252\n// gas legacyOptimized: 120370\n" + }, + "byte_array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n bytes data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop_empty_exception.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated.sol b/examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated.sol new file mode 100644 index 00000000..f7422171 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated.sol @@ -0,0 +1,12 @@ +// This tests that the compiler knows the correct size of the function on the stack. +contract c { + bytes data; + + function test() public returns (uint256 x) { + x = 2; + data.pop; + x = 3; + } +} +// ---- +// test() -> 3 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated_standard_input.json new file mode 100644 index 00000000..3e14ebcb --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_isolated/byte_array_pop_isolated_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_empty_exception.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "array_pop_uint24_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint24[] data;\n function test() public returns (uint24 x, uint24 y) {\n for (uint i = 1; i <= 30; i++)\n data.push(uint24(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n }\n}\n// ----\n// test() -> 20, 10\n// gas irOptimized: 125889\n// gas legacy: 127215\n// gas legacyOptimized: 122224\n// storageEmpty -> 1\n" + }, + "byte_array_pop_masking_long.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bytes memory) {\n for (uint256 i = 0; i < 34; i++) data.push(0x03);\n data.pop();\n return data;\n }\n}\n// ----\n// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 106762\n// gas legacy: 121252\n// gas legacyOptimized: 120370\n" + }, + "byte_array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n bytes data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty.sol b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty.sol new file mode 100644 index 00000000..18afa649 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty.sol @@ -0,0 +1,22 @@ +contract c { + uint256 a; + uint256 b; + uint256 c; + bytes data; + function test() public returns (bool) { + for (uint8 i = 0; i <= 40; i++) + data.push(bytes1(i+1)); + for (int8 j = 40; j >= 0; j--) { + require(data[uint8(j)] == bytes1(uint8(j+1))); + require(data.length == uint8(j+1)); + data.pop(); + } + return true; + } +} +// ---- +// test() -> true +// gas irOptimized: 138795 +// gas legacy: 178396 +// gas legacyOptimized: 163832 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty_standard_input.json new file mode 100644 index 00000000..6756b8a4 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty/byte_array_pop_long_storage_empty_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref.sol b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref.sol new file mode 100644 index 00000000..cbb10a0a --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref.sol @@ -0,0 +1,21 @@ +contract c { + uint256 a; + uint256 b; + bytes data; + function test() public { + for (uint8 i = 0; i <= 40; i++) + data.push(0x03); + for (uint8 j = 0; j <= 40; j++) { + assembly { + mstore(0, "garbage") + } + data.pop(); + } + } +} +// ---- +// test() -> +// gas irOptimized: 113631 +// gas legacy: 131256 +// gas legacyOptimized: 126668 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref_standard_input.json new file mode 100644 index 00000000..7965e160 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_long_storage_empty_garbage_ref/byte_array_pop_long_storage_empty_garbage_ref_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long.sol b/examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long.sol new file mode 100644 index 00000000..3ef3571f --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long.sol @@ -0,0 +1,14 @@ +contract c { + bytes data; + + function test() public returns (bytes memory) { + for (uint256 i = 0; i < 34; i++) data.push(0x03); + data.pop(); + return data; + } +} +// ---- +// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 +// gas irOptimized: 106762 +// gas legacy: 121252 +// gas legacyOptimized: 120370 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long_standard_input.json new file mode 100644 index 00000000..e60c41f8 --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_masking_long/byte_array_pop_masking_long_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_empty_exception.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (bool) {\n data.pop();\n return true;\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x31\n" + }, + "array_pop_uint24_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint24[] data;\n function test() public returns (uint24 x, uint24 y) {\n for (uint i = 1; i <= 30; i++)\n data.push(uint24(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n }\n}\n// ----\n// test() -> 20, 10\n// gas irOptimized: 125889\n// gas legacy: 127215\n// gas legacyOptimized: 122224\n// storageEmpty -> 1\n" + }, + "byte_array_pop_masking_long.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bytes memory) {\n for (uint256 i = 0; i < 34; i++) data.push(0x03);\n data.pop();\n return data;\n }\n}\n// ----\n// test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 106762\n// gas legacy: 121252\n// gas legacyOptimized: 120370\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty.sol b/examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty.sol new file mode 100644 index 00000000..a89f8a2a --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty.sol @@ -0,0 +1,14 @@ +contract c { + bytes data; + function test() public { + data.push(0x07); + data.push(0x05); + data.push(0x03); + data.pop(); + data.pop(); + data.pop(); + } +} +// ---- +// test() -> +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty_standard_input.json b/examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty_standard_input.json new file mode 100644 index 00000000..0a0523cb --- /dev/null +++ b/examples/test/semanticTests/array_pop_byte_array_pop_storage_empty/byte_array_pop_storage_empty_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + }, + "array_pop_isolated.sol": { + "content": "// This tests that the compiler knows the correct size of the function on the stack.\ncontract c {\n uint256[] data;\n\n function test() public returns (uint256 x) {\n x = 2;\n data.pop;\n x = 3;\n }\n}\n// ----\n// test() -> 3\n" + }, + "byte_array_pop.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (uint256 x, uint256 y, uint256 l) {\n data.push(0x07);\n data.push(0x03);\n x = data.length;\n data.pop();\n data.pop();\n data.push(0x02);\n y = data.length;\n l = data.length;\n }\n}\n// ----\n// test() -> 2, 1, 1\n" + }, + "array_pop.sol": { + "content": "contract c {\n uint256[] data;\n\n function test() public returns (uint256 x, uint256 l) {\n data.push(7);\n data.push(3);\n x = data.length;\n data.pop();\n x = data.length;\n data.pop();\n l = data.length;\n }\n}\n// ----\n// test() -> 1, 0\n" + }, + "array_pop_storage_empty.sol": { + "content": "contract c {\n uint[] data;\n function test() public {\n data.push(7);\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + }, + "array_pop_array_transition.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n uint16[] inner = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];\n uint16[][] data;\n function test() public returns (uint x, uint y, uint z) {\n for (uint i = 1; i <= 48; i++)\n data.push(inner);\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1][0];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1][1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1][2];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n delete inner;\n }\n}\n// ----\n// test() -> 1, 2, 3\n// gas irOptimized: 1828226\n// gas legacy: 1822464\n// gas legacyOptimized: 1813404\n// storageEmpty -> 1\n" + }, + "array_pop_uint16_transition.sol": { + "content": "contract c {\n uint16[] data;\n function test() public returns (uint16 x, uint16 y, uint16 z) {\n for (uint i = 1; i <= 48; i++)\n data.push(uint16(i));\n for (uint j = 1; j <= 10; j++)\n data.pop();\n x = data[data.length - 1];\n for (uint k = 1; k <= 10; k++)\n data.pop();\n y = data[data.length - 1];\n for (uint l = 1; l <= 10; l++)\n data.pop();\n z = data[data.length - 1];\n for (uint m = 1; m <= 18; m++)\n data.pop();\n }\n}\n// ----\n// test() -> 38, 28, 18\n// gas irOptimized: 148380\n// gas legacy: 151182\n// gas legacyOptimized: 142418\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n uint256 c;\n bytes data;\n function test() public returns (bool) {\n for (uint8 i = 0; i <= 40; i++)\n data.push(bytes1(i+1));\n for (int8 j = 40; j >= 0; j--) {\n require(data[uint8(j)] == bytes1(uint8(j+1)));\n require(data.length == uint8(j+1));\n data.pop();\n }\n return true;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 138795\n// gas legacy: 178396\n// gas legacyOptimized: 163832\n// storageEmpty -> 1\n" + }, + "byte_array_pop_long_storage_empty_garbage_ref.sol": { + "content": "contract c {\n uint256 a;\n uint256 b;\n bytes data;\n function test() public {\n for (uint8 i = 0; i <= 40; i++)\n data.push(0x03);\n for (uint8 j = 0; j <= 40; j++) {\n assembly {\n mstore(0, \"garbage\")\n }\n data.pop();\n }\n }\n}\n// ----\n// test() ->\n// gas irOptimized: 113631\n// gas legacy: 131256\n// gas legacyOptimized: 126668\n// storageEmpty -> 1\n" + }, + "byte_array_pop_storage_empty.sol": { + "content": "contract c {\n bytes data;\n function test() public {\n data.push(0x07);\n data.push(0x05);\n data.push(0x03);\n data.pop();\n data.pop();\n data.pop();\n }\n}\n// ----\n// test() ->\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_pop_parenthesized/parenthesized.sol b/examples/test/semanticTests/array_pop_parenthesized/parenthesized.sol new file mode 100644 index 00000000..478040fd --- /dev/null +++ b/examples/test/semanticTests/array_pop_parenthesized/parenthesized.sol @@ -0,0 +1,10 @@ +contract C { + int[] data; + function f() public returns (uint) { + data.push(1); + (data.pop)(); + return data.length; + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/array_pop_parenthesized/parenthesized_standard_input.json b/examples/test/semanticTests/array_pop_parenthesized/parenthesized_standard_input.json new file mode 100644 index 00000000..c5ec5301 --- /dev/null +++ b/examples/test/semanticTests/array_pop_parenthesized/parenthesized_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "parenthesized.sol": { + "content": "contract C {\n int[] data;\n function f() public returns (uint) {\n data.push(1);\n (data.pop)();\n return data.length;\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push/array_push.sol b/examples/test/semanticTests/array_push_array_push/array_push.sol new file mode 100644 index 00000000..b8eab873 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push/array_push.sol @@ -0,0 +1,21 @@ +contract c { + uint256[] data; + + function test() + public + returns (uint256 x, uint256 y, uint256 z, uint256 l) + { + data.push(5); + x = data[0]; + data.push(4); + y = data[1]; + data.push(3); + l = data.length; + z = data[2]; + } +} +// ---- +// test() -> 5, 4, 3, 3 +// gas irOptimized: 111834 +// gas legacy: 111804 +// gas legacyOptimized: 111122 diff --git a/examples/test/semanticTests/array_push_array_push/array_push_standard_input.json b/examples/test/semanticTests/array_push_array_push/array_push_standard_input.json new file mode 100644 index 00000000..0c68d989 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push/array_push_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push_nested/array_push_nested.sol b/examples/test/semanticTests/array_push_array_push_nested/array_push_nested.sol new file mode 100644 index 00000000..a86679d3 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_nested/array_push_nested.sol @@ -0,0 +1,15 @@ +contract C { + uint8 b = 23; + uint120[][] s; + uint8 a = 17; + function f() public { + s.push(); + assert(s.length == 1); + assert(s[0].length == 0); + s[0].push(); + assert(s[0].length == 1); + assert(s[0][0] == 0); + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/array_push_array_push_nested/array_push_nested_standard_input.json b/examples/test/semanticTests/array_push_array_push_nested/array_push_nested_standard_input.json new file mode 100644 index 00000000..90851877 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_nested/array_push_nested_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata.sol b/examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata.sol new file mode 100644 index 00000000..77ae8c4e --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata.sol @@ -0,0 +1,17 @@ +contract C { + uint8 b = 23; + uint120[][] s; + uint8 a = 17; + function f(uint120[] calldata c) public returns(uint120) { + s.push(c); + assert(s.length == 1); + assert(s[0].length == c.length); + assert(s[0].length > 0); + return s[0][0]; + } +} +// ---- +// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 +// gas irOptimized: 112852 +// gas legacy: 113657 +// gas legacyOptimized: 113465 diff --git a/examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata_standard_input.json b/examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata_standard_input.json new file mode 100644 index 00000000..fb6e22cf --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_nested_from_calldata/array_push_nested_from_calldata_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "nested_bytes_push.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public {\n a.push(\"abc\");\n a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n assert(a[0][0] == \"a\");\n assert(a[1][31] == \"h\");\n assert(a[2][32] == \"a\");\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180397\n" + }, + "array_push_nested_from_calldata.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f(uint120[] calldata c) public returns(uint120) {\n s.push(c);\n assert(s.length == 1);\n assert(s[0].length == c.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1\n// gas irOptimized: 112852\n// gas legacy: 113657\n// gas legacyOptimized: 113465\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory.sol b/examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory.sol new file mode 100644 index 00000000..0d85613f --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory.sol @@ -0,0 +1,17 @@ +contract C { + uint8 b = 23; + uint120[][] s; + uint8 a = 17; + function f() public returns(uint120) { + delete s; + uint120[] memory m = new uint120[](3); + m[0] = 1; + s.push(m); + assert(s.length == 1); + assert(s[0].length == m.length); + assert(s[0].length > 0); + return s[0][0]; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory_standard_input.json b/examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory_standard_input.json new file mode 100644 index 00000000..62f0068a --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_nested_from_memory/array_push_nested_from_memory_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array.sol b/examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array.sol new file mode 100644 index 00000000..e7a3bdbd --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array.sol @@ -0,0 +1,18 @@ +contract c { + uint80[] x; + + function test() public returns (uint80, uint80, uint80, uint80) { + x.push(1); + x.push(2); + x.push(3); + x.push(4); + x.push(5); + x.pop(); + return (x[0], x[1], x[2], x[3]); + } +} +// ---- +// test() -> 1, 2, 3, 4 +// gas irOptimized: 93017 +// gas legacy: 92798 +// gas legacyOptimized: 92062 diff --git a/examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array_standard_input.json b/examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array_standard_input.json new file mode 100644 index 00000000..4d96586f --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_packed_array/array_push_packed_array_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push_struct/array_push_struct.sol b/examples/test/semanticTests/array_push_array_push_struct/array_push_struct.sol new file mode 100644 index 00000000..92f071e1 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_struct/array_push_struct.sol @@ -0,0 +1,25 @@ +contract c { + struct S { + uint16 a; + uint16 b; + uint16[3] c; + uint16[] d; + } + S[] data; + + function test() public returns (uint16, uint16, uint16, uint16) { + S memory s; + s.a = 2; + s.b = 3; + s.c[2] = 4; + s.d = new uint16[](4); + s.d[2] = 5; + data.push(s); + return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]); + } +} +// ---- +// test() -> 2, 3, 4, 5 +// gas irOptimized: 135329 +// gas legacy: 147437 +// gas legacyOptimized: 146429 diff --git a/examples/test/semanticTests/array_push_array_push_struct/array_push_struct_standard_input.json b/examples/test/semanticTests/array_push_array_push_struct/array_push_struct_standard_input.json new file mode 100644 index 00000000..cf25f014 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_struct/array_push_struct_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "nested_bytes_push.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public {\n a.push(\"abc\");\n a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n assert(a[0][0] == \"a\");\n assert(a[1][31] == \"h\");\n assert(a[2][32] == \"a\");\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180397\n" + }, + "array_push_nested_from_calldata.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f(uint120[] calldata c) public returns(uint120) {\n s.push(c);\n assert(s.length == 1);\n assert(s[0].length == c.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1\n// gas irOptimized: 112852\n// gas legacy: 113657\n// gas legacyOptimized: 113465\n" + }, + "array_push_struct_from_calldata.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n struct S {\n uint16 a;\n uint16 b;\n uint16[3] c;\n uint16[] d;\n }\n S[] data;\n\n function test(S calldata c) public returns (uint16, uint16, uint16, uint16) {\n data.push(c);\n return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n }\n}\n// ----\n// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5\n// gas irOptimized: 137153\n// gas legacy: 142414\n// gas legacyOptimized: 137975\n" + }, + "byte_array_push.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bool x) {\n data.push(0x05);\n if (data.length != 1) return true;\n if (data[0] != 0x05) return true;\n data.push(0x04);\n if (data[1] != 0x04) return true;\n data.push(0x03);\n uint256 l = data.length;\n if (data[2] != 0x03) return true;\n if (l != 0x03) return true;\n }\n}\n// ----\n// test() -> false\n" + }, + "array_push_struct.sol": { + "content": "contract c {\n struct S {\n uint16 a;\n uint16 b;\n uint16[3] c;\n uint16[] d;\n }\n S[] data;\n\n function test() public returns (uint16, uint16, uint16, uint16) {\n S memory s;\n s.a = 2;\n s.b = 3;\n s.c[2] = 4;\n s.d = new uint16[](4);\n s.d[2] = 5;\n data.push(s);\n return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n }\n}\n// ----\n// test() -> 2, 3, 4, 5\n// gas irOptimized: 135329\n// gas legacy: 147437\n// gas legacyOptimized: 146429\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata.sol b/examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata.sol new file mode 100644 index 00000000..254c14b0 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract c { + struct S { + uint16 a; + uint16 b; + uint16[3] c; + uint16[] d; + } + S[] data; + + function test(S calldata c) public returns (uint16, uint16, uint16, uint16) { + data.push(c); + return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]); + } +} +// ---- +// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5 +// gas irOptimized: 137153 +// gas legacy: 142414 +// gas legacyOptimized: 137975 diff --git a/examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata_standard_input.json b/examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata_standard_input.json new file mode 100644 index 00000000..39b78853 --- /dev/null +++ b/examples/test/semanticTests/array_push_array_push_struct_from_calldata/array_push_struct_from_calldata_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "nested_bytes_push.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public {\n a.push(\"abc\");\n a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n assert(a[0][0] == \"a\");\n assert(a[1][31] == \"h\");\n assert(a[2][32] == \"a\");\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180397\n" + }, + "array_push_nested_from_calldata.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f(uint120[] calldata c) public returns(uint120) {\n s.push(c);\n assert(s.length == 1);\n assert(s[0].length == c.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1\n// gas irOptimized: 112852\n// gas legacy: 113657\n// gas legacyOptimized: 113465\n" + }, + "array_push_struct_from_calldata.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n struct S {\n uint16 a;\n uint16 b;\n uint16[3] c;\n uint16[] d;\n }\n S[] data;\n\n function test(S calldata c) public returns (uint16, uint16, uint16, uint16) {\n data.push(c);\n return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n }\n}\n// ----\n// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5\n// gas irOptimized: 137153\n// gas legacy: 142414\n// gas legacyOptimized: 137975\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_byte_array_push/byte_array_push.sol b/examples/test/semanticTests/array_push_byte_array_push/byte_array_push.sol new file mode 100644 index 00000000..2e0288d2 --- /dev/null +++ b/examples/test/semanticTests/array_push_byte_array_push/byte_array_push.sol @@ -0,0 +1,17 @@ +contract c { + bytes data; + + function test() public returns (bool x) { + data.push(0x05); + if (data.length != 1) return true; + if (data[0] != 0x05) return true; + data.push(0x04); + if (data[1] != 0x04) return true; + data.push(0x03); + uint256 l = data.length; + if (data[2] != 0x03) return true; + if (l != 0x03) return true; + } +} +// ---- +// test() -> false diff --git a/examples/test/semanticTests/array_push_byte_array_push/byte_array_push_standard_input.json b/examples/test/semanticTests/array_push_byte_array_push/byte_array_push_standard_input.json new file mode 100644 index 00000000..80b217e8 --- /dev/null +++ b/examples/test/semanticTests/array_push_byte_array_push/byte_array_push_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "nested_bytes_push.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public {\n a.push(\"abc\");\n a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n assert(a[0][0] == \"a\");\n assert(a[1][31] == \"h\");\n assert(a[2][32] == \"a\");\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180397\n" + }, + "array_push_nested_from_calldata.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f(uint120[] calldata c) public returns(uint120) {\n s.push(c);\n assert(s.length == 1);\n assert(s[0].length == c.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1\n// gas irOptimized: 112852\n// gas legacy: 113657\n// gas legacyOptimized: 113465\n" + }, + "array_push_struct_from_calldata.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n struct S {\n uint16 a;\n uint16 b;\n uint16[3] c;\n uint16[] d;\n }\n S[] data;\n\n function test(S calldata c) public returns (uint16, uint16, uint16, uint16) {\n data.push(c);\n return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n }\n}\n// ----\n// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5\n// gas irOptimized: 137153\n// gas legacy: 142414\n// gas legacyOptimized: 137975\n" + }, + "byte_array_push.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bool x) {\n data.push(0x05);\n if (data.length != 1) return true;\n if (data[0] != 0x05) return true;\n data.push(0x04);\n if (data[1] != 0x04) return true;\n data.push(0x03);\n uint256 l = data.length;\n if (data[2] != 0x03) return true;\n if (l != 0x03) return true;\n }\n}\n// ----\n// test() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition.sol b/examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition.sol new file mode 100644 index 00000000..ffc47eaa --- /dev/null +++ b/examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition.sol @@ -0,0 +1,20 @@ +// Tests transition between short and long encoding +contract c { + bytes data; + + function test() public returns (uint256) { + for (uint8 i = 1; i < 40; i++) { + data.push(bytes1(i)); + if (data.length != i) return 0x1000 + i; + if (data[data.length - 1] != bytes1(i)) return i; + } + for (uint8 i = 1; i < 40; i++) + if (data[i - 1] != bytes1(i)) return 0x1000000 + i; + return 0; + } +} +// ---- +// test() -> 0 +// gas irOptimized: 167569 +// gas legacy: 206218 +// gas legacyOptimized: 197297 diff --git a/examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition_standard_input.json b/examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition_standard_input.json new file mode 100644 index 00000000..700456f3 --- /dev/null +++ b/examples/test/semanticTests/array_push_byte_array_push_transition/byte_array_push_transition_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push.sol b/examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push.sol new file mode 100644 index 00000000..5633199d --- /dev/null +++ b/examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; +contract C { + bytes[] a; + + function f() public { + a.push("abc"); + a.push("abcdefghabcdefghabcdefghabcdefgh"); + a.push("abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh"); + assert(a[0][0] == "a"); + assert(a[1][31] == "h"); + assert(a[2][32] == "a"); + } +} +// ---- +// f() -> +// gas irOptimized: 179534 +// gas legacy: 181013 +// gas legacyOptimized: 180397 diff --git a/examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push_standard_input.json b/examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push_standard_input.json new file mode 100644 index 00000000..49517748 --- /dev/null +++ b/examples/test/semanticTests/array_push_nested_bytes_push/nested_bytes_push_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "nested_bytes_push.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public {\n a.push(\"abc\");\n a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n assert(a[0][0] == \"a\");\n assert(a[1][31] == \"h\");\n assert(a[2][32] == \"a\");\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180397\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d.sol b/examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d.sol new file mode 100644 index 00000000..cf6f0687 --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d.sol @@ -0,0 +1,32 @@ +contract C { + uint[] array; + + function f() public returns (uint) { + uint y = array.push(); + return y; + } + + function lv(uint value) public { + array.push() = value; + } + + function a(uint index) public view returns (uint) { + return array[index]; + } + + function l() public view returns (uint) { + return array.length; + } + +} +// ---- +// l() -> 0 +// lv(uint256): 42 -> +// l() -> 1 +// a(uint256): 0 -> 42 +// f() -> 0 +// l() -> 2 +// a(uint256): 1 -> 0 +// lv(uint256): 111 -> +// l() -> 3 +// a(uint256): 2 -> 111 diff --git a/examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d_standard_input.json b/examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d_standard_input.json new file mode 100644 index 00000000..f97ef5fa --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_1d/push_no_args_1d_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d.sol b/examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d.sol new file mode 100644 index 00000000..3b35719d --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d.sol @@ -0,0 +1,45 @@ +contract C { + uint[][] array2d; + + function l() public returns (uint) { + return array2d.length; + } + + function ll(uint index) public returns (uint) { + return array2d[index].length; + } + + function a(uint i, uint j) public returns (uint) { + return array2d[i][j]; + } + + function f(uint index, uint value) public { + uint[] storage pointer = array2d.push(); + for (uint i = 0; i <= index; ++i) + pointer.push(); + pointer[index] = value; + } + + function lv(uint value) public { + array2d.push().push() = value; + } +} +// ---- +// l() -> 0 +// f(uint256,uint256): 42, 64 -> +// gas irOptimized: 112288 +// gas legacy: 107925 +// gas legacyOptimized: 101896 +// l() -> 1 +// ll(uint256): 0 -> 43 +// a(uint256,uint256): 0, 42 -> 64 +// f(uint256,uint256): 84, 128 -> +// gas irOptimized: 118708 +// gas legacy: 109977 +// gas legacyOptimized: 96331 +// l() -> 2 +// ll(uint256): 1 -> 85 +// a(uint256,uint256): 0, 42 -> 64 +// a(uint256,uint256): 1, 84 -> 128 +// lv(uint256): 512 -> +// a(uint256,uint256): 2, 0 -> 512 diff --git a/examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d_standard_input.json b/examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d_standard_input.json new file mode 100644 index 00000000..f7dafbf6 --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_2d/push_no_args_2d_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + }, + "array_push_nested_from_memory.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public returns(uint120) {\n delete s;\n uint120[] memory m = new uint120[](3);\n m[0] = 1;\n s.push(m);\n assert(s.length == 1);\n assert(s[0].length == m.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "nested_bytes_push.sol": { + "content": "pragma abicoder v2;\ncontract C {\n bytes[] a;\n\n function f() public {\n a.push(\"abc\");\n a.push(\"abcdefghabcdefghabcdefghabcdefgh\");\n a.push(\"abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh\");\n assert(a[0][0] == \"a\");\n assert(a[1][31] == \"h\");\n assert(a[2][32] == \"a\");\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 179534\n// gas legacy: 181013\n// gas legacyOptimized: 180397\n" + }, + "array_push_nested_from_calldata.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f(uint120[] calldata c) public returns(uint120) {\n s.push(c);\n assert(s.length == 1);\n assert(s[0].length == c.length);\n assert(s[0].length > 0);\n return s[0][0];\n }\n}\n// ----\n// f(uint120[]): 0x20, 3, 1, 2, 3 -> 1\n// gas irOptimized: 112852\n// gas legacy: 113657\n// gas legacyOptimized: 113465\n" + }, + "array_push_struct_from_calldata.sol": { + "content": "pragma abicoder v2;\n\ncontract c {\n struct S {\n uint16 a;\n uint16 b;\n uint16[3] c;\n uint16[] d;\n }\n S[] data;\n\n function test(S calldata c) public returns (uint16, uint16, uint16, uint16) {\n data.push(c);\n return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n }\n}\n// ----\n// test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5\n// gas irOptimized: 137153\n// gas legacy: 142414\n// gas legacyOptimized: 137975\n" + }, + "byte_array_push.sol": { + "content": "contract c {\n bytes data;\n\n function test() public returns (bool x) {\n data.push(0x05);\n if (data.length != 1) return true;\n if (data[0] != 0x05) return true;\n data.push(0x04);\n if (data[1] != 0x04) return true;\n data.push(0x03);\n uint256 l = data.length;\n if (data[2] != 0x03) return true;\n if (l != 0x03) return true;\n }\n}\n// ----\n// test() -> false\n" + }, + "array_push_struct.sol": { + "content": "contract c {\n struct S {\n uint16 a;\n uint16 b;\n uint16[3] c;\n uint16[] d;\n }\n S[] data;\n\n function test() public returns (uint16, uint16, uint16, uint16) {\n S memory s;\n s.a = 2;\n s.b = 3;\n s.c[2] = 4;\n s.d = new uint16[](4);\n s.d[2] = 5;\n data.push(s);\n return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);\n }\n}\n// ----\n// test() -> 2, 3, 4, 5\n// gas irOptimized: 135329\n// gas legacy: 147437\n// gas legacyOptimized: 146429\n" + }, + "push_no_args_2d.sol": { + "content": "contract C {\n\tuint[][] array2d;\n\n\tfunction l() public returns (uint) {\n\t\treturn array2d.length;\n\t}\n\n\tfunction ll(uint index) public returns (uint) {\n\t\treturn array2d[index].length;\n\t}\n\n\tfunction a(uint i, uint j) public returns (uint) {\n\t\treturn array2d[i][j];\n\t}\n\n\tfunction f(uint index, uint value) public {\n\t\tuint[] storage pointer = array2d.push();\n\t\tfor (uint i = 0; i <= index; ++i)\n\t\t\tpointer.push();\n\t\tpointer[index] = value;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray2d.push().push() = value;\n\t}\n}\n// ----\n// l() -> 0\n// f(uint256,uint256): 42, 64 ->\n// gas irOptimized: 112288\n// gas legacy: 107925\n// gas legacyOptimized: 101896\n// l() -> 1\n// ll(uint256): 0 -> 43\n// a(uint256,uint256): 0, 42 -> 64\n// f(uint256,uint256): 84, 128 ->\n// gas irOptimized: 118708\n// gas legacy: 109977\n// gas legacyOptimized: 96331\n// l() -> 2\n// ll(uint256): 1 -> 85\n// a(uint256,uint256): 0, 42 -> 64\n// a(uint256,uint256): 1, 84 -> 128\n// lv(uint256): 512 ->\n// a(uint256,uint256): 2, 0 -> 512\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes.sol b/examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes.sol new file mode 100644 index 00000000..de737593 --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes.sol @@ -0,0 +1,31 @@ +contract C { + bytes array; + + function f() public { + array.push(); + } + + function g(uint x) public { + for (uint i = 0; i < x; ++i) + array.push() = bytes1(uint8(i)); + } + + function l() public returns (uint) { + return array.length; + } + + function a(uint index) public view returns (bytes1) { + return array[index]; + } +} +// ---- +// l() -> 0 +// g(uint256): 70 -> +// gas irOptimized: 181778 +// gas legacy: 175192 +// gas legacyOptimized: 175005 +// l() -> 70 +// a(uint256): 69 -> left(69) +// f() -> +// l() -> 71 +// a(uint256): 70 -> 0 diff --git a/examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes_standard_input.json b/examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes_standard_input.json new file mode 100644 index 00000000..8baf94ec --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_bytes/push_no_args_bytes_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct.sol b/examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct.sol new file mode 100644 index 00000000..6f626d9c --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct.sol @@ -0,0 +1,44 @@ +contract C { + struct S { + uint x; + } + + S[] array; + + function f(uint y) public { + S storage s = array.push(); + g(s, y); + } + + function g(S storage s, uint y) internal { + s.x = y; + } + + function h(uint y) public { + g(array.push(), y); + } + + function lv(uint y) public { + array.push().x = y; + } + + function a(uint i) public returns (uint) { + return array[i].x; + } + + function l() public returns (uint) { + return array.length; + } + +} +// ---- +// l() -> 0 +// f(uint256): 42 -> +// l() -> 1 +// a(uint256): 0 -> 42 +// h(uint256): 84 -> +// l() -> 2 +// a(uint256): 1 -> 84 +// lv(uint256): 4096 -> +// l() -> 3 +// a(uint256): 2 -> 4096 diff --git a/examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct_standard_input.json b/examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct_standard_input.json new file mode 100644 index 00000000..c5886d4e --- /dev/null +++ b/examples/test/semanticTests/array_push_push_no_args_struct/push_no_args_struct_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "push_no_args_1d.sol": { + "content": "contract C {\n\tuint[] array;\n\n\tfunction f() public returns (uint) {\n\t\tuint y = array.push();\n\t\treturn y;\n\t}\n\n\tfunction lv(uint value) public {\n\t\tarray.push() = value;\n\t}\n\n\tfunction a(uint index) public view returns (uint) {\n\t\treturn array[index];\n\t}\n\n\tfunction l() public view returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// lv(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// f() -> 0\n// l() -> 2\n// a(uint256): 1 -> 0\n// lv(uint256): 111 ->\n// l() -> 3\n// a(uint256): 2 -> 111\n" + }, + "array_push.sol": { + "content": "contract c {\n uint256[] data;\n\n function test()\n public\n returns (uint256 x, uint256 y, uint256 z, uint256 l)\n {\n data.push(5);\n x = data[0];\n data.push(4);\n y = data[1];\n data.push(3);\n l = data.length;\n z = data[2];\n }\n}\n// ----\n// test() -> 5, 4, 3, 3\n// gas irOptimized: 111834\n// gas legacy: 111804\n// gas legacyOptimized: 111122\n" + }, + "array_push_nested.sol": { + "content": "contract C {\n uint8 b = 23;\n uint120[][] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s.length == 1);\n assert(s[0].length == 0);\n s[0].push();\n assert(s[0].length == 1);\n assert(s[0][0] == 0);\n }\n}\n// ----\n// f() ->\n" + }, + "array_push_packed_array.sol": { + "content": "contract c {\n uint80[] x;\n\n function test() public returns (uint80, uint80, uint80, uint80) {\n x.push(1);\n x.push(2);\n x.push(3);\n x.push(4);\n x.push(5);\n x.pop();\n return (x[0], x[1], x[2], x[3]);\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n// gas irOptimized: 93017\n// gas legacy: 92798\n// gas legacyOptimized: 92062\n" + }, + "push_no_args_bytes.sol": { + "content": "contract C {\n\tbytes array;\n\n\tfunction f() public {\n\t\tarray.push();\n\t}\n\n\tfunction g(uint x) public {\n\t\tfor (uint i = 0; i < x; ++i)\n\t\t\tarray.push() = bytes1(uint8(i));\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n\tfunction a(uint index) public view returns (bytes1) {\n\t\treturn array[index];\n\t}\n}\n// ----\n// l() -> 0\n// g(uint256): 70 ->\n// gas irOptimized: 181778\n// gas legacy: 175192\n// gas legacyOptimized: 175005\n// l() -> 70\n// a(uint256): 69 -> left(69)\n// f() ->\n// l() -> 71\n// a(uint256): 70 -> 0\n" + }, + "byte_array_push_transition.sol": { + "content": "// Tests transition between short and long encoding\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 1; i < 40; i++) {\n data.push(bytes1(i));\n if (data.length != i) return 0x1000 + i;\n if (data[data.length - 1] != bytes1(i)) return i;\n }\n for (uint8 i = 1; i < 40; i++)\n if (data[i - 1] != bytes1(i)) return 0x1000000 + i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 167569\n// gas legacy: 206218\n// gas legacyOptimized: 197297\n" + }, + "push_no_args_struct.sol": { + "content": "contract C {\n\tstruct S {\n\t\tuint x;\n\t}\n\n\tS[] array;\n\n\tfunction f(uint y) public {\n\t\tS storage s = array.push();\n\t\tg(s, y);\n\t}\n\n\tfunction g(S storage s, uint y) internal {\n\t\ts.x = y;\n\t}\n\n\tfunction h(uint y) public {\n\t\tg(array.push(), y);\n\t}\n\n\tfunction lv(uint y) public {\n\t\tarray.push().x = y;\n\t}\n\n\tfunction a(uint i) public returns (uint) {\n\t\treturn array[i].x;\n\t}\n\n\tfunction l() public returns (uint) {\n\t\treturn array.length;\n\t}\n\n}\n// ----\n// l() -> 0\n// f(uint256): 42 ->\n// l() -> 1\n// a(uint256): 0 -> 42\n// h(uint256): 84 ->\n// l() -> 2\n// a(uint256): 1 -> 84\n// lv(uint256): 4096 ->\n// l() -> 3\n// a(uint256): 2 -> 4096\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_reusing_memory/reusing_memory.sol b/examples/test/semanticTests/array_reusing_memory/reusing_memory.sol new file mode 100644 index 00000000..fd352dd6 --- /dev/null +++ b/examples/test/semanticTests/array_reusing_memory/reusing_memory.sol @@ -0,0 +1,32 @@ +// Invoke some features that use memory and test that they do not interfere with each other. +contract Helper { + uint256 public flag; + + constructor(uint256 x) { + flag = x; + } +} + + +contract Main { + mapping(uint256 => uint256) map; + + function f(uint256 x) public returns (uint256) { + map[x] = x; + return + (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x])))))) + .flag(); + } + + function g(uint256 a) public returns (uint256) { + return map[a]; + } +} +// ---- +// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 +// gas irOptimized: 99552 +// gas irOptimized code: 12400 +// gas legacy: 101551 +// gas legacy code: 23600 +// gas legacyOptimized: 99612 +// gas legacyOptimized code: 13400 diff --git a/examples/test/semanticTests/array_reusing_memory/reusing_memory_standard_input.json b/examples/test/semanticTests/array_reusing_memory/reusing_memory_standard_input.json new file mode 100644 index 00000000..dd6ff30b --- /dev/null +++ b/examples/test/semanticTests/array_reusing_memory/reusing_memory_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup.sol b/examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup.sol new file mode 100644 index 00000000..8288e1e8 --- /dev/null +++ b/examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup.sol @@ -0,0 +1,15 @@ +contract c { + uint spacer1; + uint spacer2; + uint[3] data; + function fill() public { + for (uint i = 0; i < data.length; ++i) data[i] = i+1; + } + function clear() public { delete data; } +} +// ---- +// storageEmpty -> 1 +// fill() -> +// storageEmpty -> 0 +// clear() -> +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup_standard_input.json b/examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup_standard_input.json new file mode 100644 index 00000000..0c82eb2d --- /dev/null +++ b/examples/test/semanticTests/array_short_fixed_array_cleanup/short_fixed_array_cleanup_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment.sol b/examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment.sol new file mode 100644 index 00000000..c9c489a8 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint256[] calldata x, uint256[] calldata y, uint256 i) external returns (uint256) { + x = y; + return x[i]; + } +} +// ---- +// f(uint256[],uint256[],uint256): 0x60, 0xA0, 1, 1, 0, 2, 1, 2 -> 2 diff --git a/examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment_standard_input.json b/examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment_standard_input.json new file mode 100644 index 00000000..8582451f --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_calldata_assignment/array_calldata_assignment_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "array_slice_calldata_to_memory.sol": { + "content": "contract C {\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n int[] memory m = b[start:end];\n uint len = end - start;\n assert(len == m.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == m[i]);\n }\n return [b[start:end]][0][0];\n }\n\n function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return b[start:end];\n }\n\n function h1(int[] memory b) internal returns (int[] memory) {\n return b;\n }\n\n function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return h1(b[start:end]);\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n" + }, + "array_slice_calldata_to_storage.sol": { + "content": "contract C {\n int[] s;\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n s = b[start:end];\n uint len = end - start;\n assert(len == s.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == s[i]);\n }\n return s[0];\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n" + }, + "array_calldata_assignment.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256[] calldata y, uint256 i) external returns (uint256) {\n x = y;\n return x[i];\n }\n}\n// ----\n// f(uint256[],uint256[],uint256): 0x60, 0xA0, 1, 1, 0, 2, 1, 2 -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls.sol b/examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls.sol new file mode 100644 index 00000000..079364d2 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls.sol @@ -0,0 +1,37 @@ +contract C { + function f1(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) { + return keccak256(c1[s:e]) == keccak256(c2); + } + + function f2(bytes calldata c, uint256 s) public returns (uint256, bytes memory) { + return abi.decode(c[s:], (uint256, bytes)); + } + + function f3(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) { + bytes memory a = abi.encode(c1[s:e]); + bytes memory b = abi.encode(c2); + if (a.length != b.length) { return false; } + for (uint256 i = 0; i < a.length; i++) { + if (a[i] != b[i]) { return false; } + } + return true; + } + + function f4(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) { + bytes memory a = abi.encodePacked(c1[s:e]); + bytes memory b = abi.encodePacked(c2); + if (a.length != b.length) { return false; } + for (uint256 i = 0; i < a.length; i++) { + if (a[i] != b[i]) { return false; } + } + return true; + } +} +// ---- +// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, "abcdefgh", 4, "bcde" -> true +// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, "abcdefgh", 4, "bcdf" -> false +// f2(bytes,uint256): 0x40, 0, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" +// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, "abcdefgh", 4, "bcde" -> true +// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, "abcdefgh", 4, "bcdf" -> false +// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, "abcdefgh", 4, "bcde" -> true +// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, "abcdefgh", 4, "bcdf" -> false diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls_standard_input.json b/examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls_standard_input.json new file mode 100644 index 00000000..aa777f38 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_as_argument_of_external_calls/array_slice_calldata_as_argument_of_external_calls_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "array_slice_calldata_to_memory.sol": { + "content": "contract C {\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n int[] memory m = b[start:end];\n uint len = end - start;\n assert(len == m.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == m[i]);\n }\n return [b[start:end]][0][0];\n }\n\n function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return b[start:end];\n }\n\n function h1(int[] memory b) internal returns (int[] memory) {\n return b;\n }\n\n function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return h1(b[start:end]);\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n" + }, + "array_slice_calldata_to_storage.sol": { + "content": "contract C {\n int[] s;\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n s = b[start:end];\n uint len = end - start;\n assert(len == s.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == s[i]);\n }\n return s[0];\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n" + }, + "array_calldata_assignment.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256[] calldata y, uint256 i) external returns (uint256) {\n x = y;\n return x[i];\n }\n}\n// ----\n// f(uint256[],uint256[],uint256): 0x60, 0xA0, 1, 1, 0, 2, 1, 2 -> 2\n" + }, + "array_slice_calldata_as_argument_of_external_calls.sol": { + "content": "contract C {\n function f1(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n return keccak256(c1[s:e]) == keccak256(c2);\n }\n\n function f2(bytes calldata c, uint256 s) public returns (uint256, bytes memory) {\n return abi.decode(c[s:], (uint256, bytes));\n }\n\n function f3(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n bytes memory a = abi.encode(c1[s:e]);\n bytes memory b = abi.encode(c2);\n if (a.length != b.length) { return false; }\n for (uint256 i = 0; i < a.length; i++) {\n if (a[i] != b[i]) { return false; }\n }\n return true;\n }\n\n function f4(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n bytes memory a = abi.encodePacked(c1[s:e]);\n bytes memory b = abi.encodePacked(c2);\n if (a.length != b.length) { return false; }\n for (uint256 i = 0; i < a.length; i++) {\n if (a[i] != b[i]) { return false; }\n }\n return true;\n }\n}\n// ----\n// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n// f2(bytes,uint256): 0x40, 0, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata.sol b/examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata.sol new file mode 100644 index 00000000..89096c99 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 p1; + uint256[3] a; + uint32 p2; + } + function f(S[] calldata c) internal returns (S[] memory) { + return c; + } + function g(S[] calldata c, uint256 s, uint256 e) public returns (S[] memory) { + return f(c[s:e]); + } + + function f1(uint256[3][] calldata c) internal returns (uint256[3][] memory) { + return c; + } + function g1(uint256[3][] calldata c, uint256 s, uint256 e) public returns (uint256[3][] memory) { + return f1(c[s:e]); + } +} +// ---- +// g((uint128,uint256[3],uint32)[],uint256,uint256): 0x60, 1, 3, 4, 55, 1, 2, 3, 66, 66, 2, 3, 4, 77, 77, 3, 4, 5, 88, 88, 4, 5, 6, 99 -> 0x20, 2, 66, 2, 3, 4, 77, 77, 3, 4, 5, 88 +// g1(uint256[3][],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 -> 0x20, 2, 4, 5, 6, 7, 8, 9 diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata_standard_input.json b/examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata_standard_input.json new file mode 100644 index 00000000..ddbeb945 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_to_calldata/array_slice_calldata_to_calldata_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "array_slice_calldata_to_memory.sol": { + "content": "contract C {\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n int[] memory m = b[start:end];\n uint len = end - start;\n assert(len == m.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == m[i]);\n }\n return [b[start:end]][0][0];\n }\n\n function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return b[start:end];\n }\n\n function h1(int[] memory b) internal returns (int[] memory) {\n return b;\n }\n\n function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return h1(b[start:end]);\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n" + }, + "array_slice_calldata_to_storage.sol": { + "content": "contract C {\n int[] s;\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n s = b[start:end];\n uint len = end - start;\n assert(len == s.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == s[i]);\n }\n return s[0];\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n" + }, + "array_calldata_assignment.sol": { + "content": "contract C {\n function f(uint256[] calldata x, uint256[] calldata y, uint256 i) external returns (uint256) {\n x = y;\n return x[i];\n }\n}\n// ----\n// f(uint256[],uint256[],uint256): 0x60, 0xA0, 1, 1, 0, 2, 1, 2 -> 2\n" + }, + "array_slice_calldata_as_argument_of_external_calls.sol": { + "content": "contract C {\n function f1(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n return keccak256(c1[s:e]) == keccak256(c2);\n }\n\n function f2(bytes calldata c, uint256 s) public returns (uint256, bytes memory) {\n return abi.decode(c[s:], (uint256, bytes));\n }\n\n function f3(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n bytes memory a = abi.encode(c1[s:e]);\n bytes memory b = abi.encode(c2);\n if (a.length != b.length) { return false; }\n for (uint256 i = 0; i < a.length; i++) {\n if (a[i] != b[i]) { return false; }\n }\n return true;\n }\n\n function f4(bytes calldata c1, uint256 s, uint256 e, bytes calldata c2) public returns (bool) {\n bytes memory a = abi.encodePacked(c1[s:e]);\n bytes memory b = abi.encodePacked(c2);\n if (a.length != b.length) { return false; }\n for (uint256 i = 0; i < a.length; i++) {\n if (a[i] != b[i]) { return false; }\n }\n return true;\n }\n}\n// ----\n// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f1(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n// f2(bytes,uint256): 0x40, 0, 0x80, 0x21, 0x40, 0x7, \"abcdefg\" -> 0x21, 0x40, 0x7, \"abcdefg\"\n// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f3(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcde\" -> true\n// f4(bytes,uint256,uint256,bytes): 0x80, 1, 5, 0xC0, 8, \"abcdefgh\", 4, \"bcdf\" -> false\n" + }, + "array_slice_calldata_to_calldata.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[3] a;\n uint32 p2;\n }\n function f(S[] calldata c) internal returns (S[] memory) {\n return c;\n }\n function g(S[] calldata c, uint256 s, uint256 e) public returns (S[] memory) {\n return f(c[s:e]);\n }\n\n function f1(uint256[3][] calldata c) internal returns (uint256[3][] memory) {\n return c;\n }\n function g1(uint256[3][] calldata c, uint256 s, uint256 e) public returns (uint256[3][] memory) {\n return f1(c[s:e]);\n }\n}\n// ----\n// g((uint128,uint256[3],uint32)[],uint256,uint256): 0x60, 1, 3, 4, 55, 1, 2, 3, 66, 66, 2, 3, 4, 77, 77, 3, 4, 5, 88, 88, 4, 5, 6, 99 -> 0x20, 2, 66, 2, 3, 4, 77, 77, 3, 4, 5, 88\n// g1(uint256[3][],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 -> 0x20, 2, 4, 5, 6, 7, 8, 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory.sol b/examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory.sol new file mode 100644 index 00000000..e37bdf0c --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory.sol @@ -0,0 +1,27 @@ +contract C { + function f(int[] calldata b, uint256 start, uint256 end) public returns (int) { + int[] memory m = b[start:end]; + uint len = end - start; + assert(len == m.length); + for (uint i = 0; i < len; i++) { + assert(b[start:end][i] == m[i]); + } + return [b[start:end]][0][0]; + } + + function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) { + return b[start:end]; + } + + function h1(int[] memory b) internal returns (int[] memory) { + return b; + } + + function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) { + return h1(b[start:end]); + } +} +// ---- +// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2 +// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3 +// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3 diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory_standard_input.json b/examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..c6dc0b95 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_to_memory/array_slice_calldata_to_memory_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "array_slice_calldata_to_memory.sol": { + "content": "contract C {\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n int[] memory m = b[start:end];\n uint len = end - start;\n assert(len == m.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == m[i]);\n }\n return [b[start:end]][0][0];\n }\n\n function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return b[start:end];\n }\n\n function h1(int[] memory b) internal returns (int[] memory) {\n return b;\n }\n\n function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return h1(b[start:end]);\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage.sol b/examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage.sol new file mode 100644 index 00000000..b50d74e4 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage.sol @@ -0,0 +1,14 @@ +contract C { + int[] s; + function f(int[] calldata b, uint256 start, uint256 end) public returns (int) { + s = b[start:end]; + uint len = end - start; + assert(len == s.length); + for (uint i = 0; i < len; i++) { + assert(b[start:end][i] == s[i]); + } + return s[0]; + } +} +// ---- +// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2 diff --git a/examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage_standard_input.json b/examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..e3b06159 --- /dev/null +++ b/examples/test/semanticTests/array_slices_array_slice_calldata_to_storage/array_slice_calldata_to_storage_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "array_slice_calldata_to_memory.sol": { + "content": "contract C {\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n int[] memory m = b[start:end];\n uint len = end - start;\n assert(len == m.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == m[i]);\n }\n return [b[start:end]][0][0];\n }\n\n function g(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return b[start:end];\n }\n\n function h1(int[] memory b) internal returns (int[] memory) {\n return b;\n }\n\n function h(int[] calldata b, uint256 start, uint256 end) public returns (int[] memory) {\n return h1(b[start:end]);\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n// g(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n// h(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 0x20, 2, 2, 3\n" + }, + "array_slice_calldata_to_storage.sol": { + "content": "contract C {\n int[] s;\n function f(int[] calldata b, uint256 start, uint256 end) public returns (int) {\n s = b[start:end];\n uint len = end - start;\n assert(len == s.length);\n for (uint i = 0; i < len; i++) {\n assert(b[start:end][i] == s[i]);\n }\n return s[0];\n }\n}\n// ----\n// f(int256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_storage_array_ref/storage_array_ref.sol b/examples/test/semanticTests/array_storage_array_ref/storage_array_ref.sol new file mode 100644 index 00000000..37292ae8 --- /dev/null +++ b/examples/test/semanticTests/array_storage_array_ref/storage_array_ref.sol @@ -0,0 +1,57 @@ +contract BinarySearch { + /// Finds the position of _value in the sorted list _data. + /// Note that "internal" is important here, because storage references only work for internal or private functions + function find(uint256[] storage _data, uint256 _value) + internal + returns (uint256 o_position) + { + return find(_data, 0, _data.length, _value); + } + + function find( + uint256[] storage _data, + uint256 _begin, + uint256 _len, + uint256 _value + ) private returns (uint256 o_position) { + if (_len == 0 || (_len == 1 && _data[_begin] != _value)) + return type(uint256).max; // failure + uint256 halfLen = _len / 2; + uint256 v = _data[_begin + halfLen]; + if (_value < v) return find(_data, _begin, halfLen, _value); + else if (_value > v) + return find(_data, _begin + halfLen + 1, halfLen - 1, _value); + else return _begin + halfLen; + } +} + + +contract Store is BinarySearch { + uint256[] data; + + function add(uint256 v) public { + data.push(0); + data[data.length - 1] = v; + } + + function find(uint256 v) public returns (uint256) { + return find(data, v); + } +} +// ---- +// find(uint256): 7 -> -1 +// add(uint256): 7 -> +// find(uint256): 7 -> 0 +// add(uint256): 11 -> +// add(uint256): 17 -> +// add(uint256): 27 -> +// add(uint256): 31 -> +// add(uint256): 32 -> +// add(uint256): 66 -> +// add(uint256): 177 -> +// find(uint256): 7 -> 0 +// find(uint256): 27 -> 3 +// find(uint256): 32 -> 5 +// find(uint256): 176 -> -1 +// find(uint256): 0 -> -1 +// find(uint256): 400 -> -1 diff --git a/examples/test/semanticTests/array_storage_array_ref/storage_array_ref_standard_input.json b/examples/test/semanticTests/array_storage_array_ref/storage_array_ref_standard_input.json new file mode 100644 index 00000000..e9c5f62c --- /dev/null +++ b/examples/test/semanticTests/array_storage_array_ref/storage_array_ref_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug.sol b/examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug.sol new file mode 100644 index 00000000..d6dadb78 --- /dev/null +++ b/examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug.sol @@ -0,0 +1,20 @@ +contract Sample { + struct s { + uint16 x; + uint16 y; + string a; + string b; + } + s[2] public p; + + constructor() { + s memory m; + m.x = 0xbbbb; + m.y = 0xcccc; + m.a = "hello"; + m.b = "world"; + p[0] = m; + } +} +// ---- +// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, "hello", 0x05, "world" diff --git a/examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug_standard_input.json b/examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug_standard_input.json new file mode 100644 index 00000000..be6fd625 --- /dev/null +++ b/examples/test/semanticTests/array_string_allocation_bug/string_allocation_bug_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion.sol b/examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion.sol new file mode 100644 index 00000000..9578fc4f --- /dev/null +++ b/examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion.sol @@ -0,0 +1,17 @@ +contract Test { + string s; + bytes b; + + function f(string memory _s, uint256 n) public returns (bytes1) { + b = bytes(_s); + s = string(b); + return bytes(s)[n]; + } + + function l() public returns (uint256) { + return bytes(s).length; + } +} +// ---- +// f(string,uint256): 0x40, 0x02, 0x06, "abcdef" -> "c" +// l() -> 0x06 diff --git a/examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion_standard_input.json b/examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion_standard_input.json new file mode 100644 index 00000000..ca33b319 --- /dev/null +++ b/examples/test/semanticTests/array_string_bytes_conversion/string_bytes_conversion_standard_input.json @@ -0,0 +1,205 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + }, + "array_storage_length_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function set_get_length(uint256 len) public returns (uint256) {\n while(storageArray.length < len)\n storageArray.push();\n return storageArray.length;\n }\n}\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 96690\n// gas legacy: 128571\n// gas legacyOptimized: 110143\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1209116\n// gas legacy: 1689548\n// gas legacyOptimized: 1393535\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n" + }, + "inline_array_singleton.sol": { + "content": "// This caused a failure since the type was not converted to its mobile type.\ncontract C {\n function f() public returns (uint256) {\n return [4][0];\n }\n}\n// ----\n// f() -> 4\n" + }, + "storage_array_ref.sol": { + "content": "contract BinarySearch {\n /// Finds the position of _value in the sorted list _data.\n /// Note that \"internal\" is important here, because storage references only work for internal or private functions\n function find(uint256[] storage _data, uint256 _value)\n internal\n returns (uint256 o_position)\n {\n return find(_data, 0, _data.length, _value);\n }\n\n function find(\n uint256[] storage _data,\n uint256 _begin,\n uint256 _len,\n uint256 _value\n ) private returns (uint256 o_position) {\n if (_len == 0 || (_len == 1 && _data[_begin] != _value))\n return type(uint256).max; // failure\n uint256 halfLen = _len / 2;\n uint256 v = _data[_begin + halfLen];\n if (_value < v) return find(_data, _begin, halfLen, _value);\n else if (_value > v)\n return find(_data, _begin + halfLen + 1, halfLen - 1, _value);\n else return _begin + halfLen;\n }\n}\n\n\ncontract Store is BinarySearch {\n uint256[] data;\n\n function add(uint256 v) public {\n data.push(0);\n data[data.length - 1] = v;\n }\n\n function find(uint256 v) public returns (uint256) {\n return find(data, v);\n }\n}\n// ----\n// find(uint256): 7 -> -1\n// add(uint256): 7 ->\n// find(uint256): 7 -> 0\n// add(uint256): 11 ->\n// add(uint256): 17 ->\n// add(uint256): 27 ->\n// add(uint256): 31 ->\n// add(uint256): 32 ->\n// add(uint256): 66 ->\n// add(uint256): 177 ->\n// find(uint256): 7 -> 0\n// find(uint256): 27 -> 3\n// find(uint256): 32 -> 5\n// find(uint256): 176 -> -1\n// find(uint256): 0 -> -1\n// find(uint256): 400 -> -1\n" + }, + "array_storage_push_empty_length_address.sol": { + "content": "contract C {\n address[] addressArray;\n function set_get_length(uint256 len) public returns (uint256)\n {\n while(addressArray.length < len)\n addressArray.push();\n while(addressArray.length > len)\n addressArray.pop();\n return addressArray.length;\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// set_get_length(uint256): 0 -> 0\n// set_get_length(uint256): 1 -> 1\n// set_get_length(uint256): 10 -> 10\n// set_get_length(uint256): 20 -> 20\n// set_get_length(uint256): 0 -> 0\n// gas irOptimized: 77628\n// gas legacy: 77730\n// gas legacyOptimized: 77162\n// set_get_length(uint256): 0xFF -> 0xFF\n// gas irOptimized: 168565\n// gas legacy: 696850\n// gas legacyOptimized: 134488\n// set_get_length(uint256): 0xFFF -> 0xFFF\n// gas irOptimized: 1908127\n// gas legacy: 9857362\n// gas legacyOptimized: 1393660\n// set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas #\n// gas irOptimized: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "arrays_complex_from_and_to_storage.sol": { + "content": "contract Test {\n uint24[3][] public data;\n\n function set(uint24[3][] memory _data) public returns (uint256) {\n data = _data;\n return data.length;\n }\n\n function get() public returns (uint24[3][] memory) {\n return data;\n }\n}\n// ----\n// set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06\n// gas irOptimized: 185216\n// gas legacy: 211054\n// gas legacyOptimized: 206077\n// data(uint256,uint256): 0x02, 0x02 -> 0x09\n// data(uint256,uint256): 0x05, 0x01 -> 0x11\n// data(uint256,uint256): 0x06, 0x00 -> FAILURE\n// get() -> 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12\n" + }, + "byte_array_storage_layout.sol": { + "content": "contract c {\n bytes data;\n function test_short() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 15; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_long() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n assembly {\n r := sload(data.slot)\n }\n }\n\n function test_pop() public returns (uint256 r) {\n assembly {\n sstore(data.slot, 0)\n }\n for (uint8 i = 0; i < 32; i++) {\n data.push(bytes1(i));\n }\n data.pop();\n data.pop();\n assembly {\n r := sload(data.slot)\n }\n }\n}\n// ----\n// storageEmpty -> 1\n// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710\n// gas legacy: 59838\n// gas legacyOptimized: 58606\n// storageEmpty -> 0\n// test_long() -> 67\n// gas irOptimized: 89148\n// gas legacy: 101607\n// gas legacyOptimized: 100479\n// storageEmpty -> 0\n// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020\n// gas legacy: 61930\n// gas legacyOptimized: 59404\n// storageEmpty -> 0\n" + }, + "array_storage_index_access.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_indices(uint256 len) public\n {\n while (storageArray.length < len)\n storageArray.push();\n while (storageArray.length > len)\n storageArray.pop();\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == i + 1);\n }\n}\n// ----\n// test_indices(uint256): 1 ->\n// test_indices(uint256): 129 ->\n// gas irOptimized: 3017687\n// gas legacy: 3038668\n// gas legacyOptimized: 2995964\n// test_indices(uint256): 5 ->\n// gas irOptimized: 579670\n// gas legacy: 573821\n// gas legacyOptimized: 571847\n// test_indices(uint256): 10 ->\n// gas irOptimized: 157953\n// gas legacy: 160122\n// gas legacyOptimized: 156996\n// test_indices(uint256): 15 ->\n// gas irOptimized: 172733\n// gas legacy: 175987\n// gas legacyOptimized: 171596\n// test_indices(uint256): 0xFF ->\n// gas irOptimized: 5673823\n// gas legacy: 5715762\n// gas legacyOptimized: 5632556\n// test_indices(uint256): 1000 ->\n// gas irOptimized: 18173005\n// gas legacy: 18347824\n// gas legacyOptimized: 18037248\n// test_indices(uint256): 129 ->\n// gas irOptimized: 4166279\n// gas legacy: 4140124\n// gas legacyOptimized: 4108272\n// test_indices(uint256): 128 ->\n// gas irOptimized: 405522\n// gas legacy: 433512\n// gas legacyOptimized: 400909\n// test_indices(uint256): 1 ->\n// gas irOptimized: 583437\n// gas legacy: 576726\n// gas legacyOptimized: 575542\n" + }, + "invalid_encoding_for_storage_byte_array.sol": { + "content": "contract C {\n bytes public x = \"abc\";\n bytes public y;\n function invalidateXShort() public {\n assembly { sstore(x.slot, 64) }\n delete y;\n }\n function invalidateXLong() public {\n assembly { sstore(x.slot, 5) }\n delete y;\n }\n function abiEncode() public view returns (bytes memory) { return x; }\n function abiEncodePacked() public view returns (bytes memory) { return abi.encodePacked(x); }\n function copyToMemory() public view returns (bytes memory m) { m = x; }\n function indexAccess() public view returns (bytes1) { return x[0]; }\n function assignTo() public { x = \"def\"; }\n function assignToLong() public { x = \"1234567890123456789012345678901234567\"; }\n function copyToStorage() public { y = x; }\n function copyFromStorageShort() public { y = \"abc\"; x = y; }\n function copyFromStorageLong() public { y = \"1234567890123456789012345678901234567\"; x = y; }\n function arrayPop() public { x.pop(); }\n function arrayPush() public { x.push(\"t\"); }\n function arrayPushEmpty() public { x.push(); }\n function del() public { delete x; }\n}\n// ----\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncode() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// abiEncodePacked() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyToMemory() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// indexAccess() -> 0x6100000000000000000000000000000000000000000000000000000000000000\n// arrayPushEmpty()\n// arrayPush()\n// x() -> 0x20, 5, 0x6162630074000000000000000000000000000000000000000000000000000000\n// arrayPop()\n// assignToLong()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// assignTo()\n// x() -> 0x20, 3, 0x6465660000000000000000000000000000000000000000000000000000000000\n// copyFromStorageShort()\n// x() -> 0x20, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n// copyFromStorageLong()\n// gas irOptimized: 121095\n// gas legacy: 121904\n// gas legacyOptimized: 121388\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// copyToStorage()\n// x() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// y() -> 0x20, 0x25, 0x3132333435363738393031323334353637383930313233343536373839303132, 0x3334353637000000000000000000000000000000000000000000000000000000\n// del()\n// x() -> 0x20, 0x00\n// invalidateXLong()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n// del() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// invalidateXShort()\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncode() -> FAILURE, hex\"4e487b71\", 0x22\n// abiEncodePacked() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToMemory() -> FAILURE, hex\"4e487b71\", 0x22\n// indexAccess() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPushEmpty() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPush() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// arrayPop() -> FAILURE, hex\"4e487b71\", 0x22\n// assignToLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// assignTo() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageShort() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyFromStorageLong() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// copyToStorage() -> FAILURE, hex\"4e487b71\", 0x22\n// x() -> FAILURE, hex\"4e487b71\", 0x22\n// y() -> 0x20, 0x00\n" + }, + "array_storage_index_zeroed_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_zeroed_indices(uint256 len) public\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n\n for (uint i = 0; i < len; i++)\n storageArray[i] = i + 1;\n\n if (len > 3)\n {\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < 3)\n storageArray.push();\n\n for (uint i = 3; i < len; i++)\n {\n assembly {\n mstore(0, storageArray.slot)\n let pos := add(keccak256(0, 0x20), i)\n\n if iszero(eq(sload(pos), 0)) {\n revert(0, 0)\n }\n }\n }\n\n }\n\n while(storageArray.length > 0)\n storageArray.pop();\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n {\n require(storageArray[i] == 0);\n\n uint256 val = storageArray[i];\n uint256 check;\n\n assembly { check := iszero(val) }\n\n require(check == 1);\n }\n }\n}\n// ----\n// test_zeroed_indices(uint256): 1 ->\n// test_zeroed_indices(uint256): 5 ->\n// gas irOptimized: 133763\n// gas legacy: 131664\n// gas legacyOptimized: 129990\n// test_zeroed_indices(uint256): 10 ->\n// gas irOptimized: 228556\n// gas legacy: 225215\n// gas legacyOptimized: 222351\n// test_zeroed_indices(uint256): 15 ->\n// gas irOptimized: 327360\n// gas legacy: 322899\n// gas legacyOptimized: 318907\n// test_zeroed_indices(uint256): 0xFF ->\n// gas irOptimized: 5180120\n// gas legacy: 5093135\n// gas legacyOptimized: 5020523\n" + }, + "short_fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[3] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "function_memory_array.sol": { + "content": "contract C {\n function a(uint256 x) public returns (uint256) {\n return x + 1;\n }\n\n function b(uint256 x) public returns (uint256) {\n return x + 2;\n }\n\n function c(uint256 x) public returns (uint256) {\n return x + 3;\n }\n\n function d(uint256 x) public returns (uint256) {\n return x + 5;\n }\n\n function e(uint256 x) public returns (uint256) {\n return x + 8;\n }\n\n function test(uint256 x, uint256 i) public returns (uint256) {\n function(uint) internal returns (uint)[] memory arr =\n new function(uint) internal returns (uint)[](10);\n arr[0] = a;\n arr[1] = b;\n arr[2] = c;\n arr[3] = d;\n arr[4] = e;\n return arr[i](x);\n }\n}\n// ----\n// test(uint256,uint256): 10, 0 -> 11\n// test(uint256,uint256): 10, 1 -> 12\n// test(uint256,uint256): 10, 2 -> 13\n// test(uint256,uint256): 10, 3 -> 15\n// test(uint256,uint256): 10, 4 -> 18\n// test(uint256,uint256): 10, 5 -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "fixed_arrays_in_storage.sol": { + "content": "contract c {\n struct Data {\n uint256 x;\n uint256 y;\n }\n Data[2**10] data;\n uint256[2**10 + 3] ids;\n\n function setIDStatic(uint256 id) public {\n ids[2] = id;\n }\n\n function setID(uint256 index, uint256 id) public {\n ids[index] = id;\n }\n\n function setData(uint256 index, uint256 x, uint256 y) public {\n data[index].x = x;\n data[index].y = y;\n }\n\n function getID(uint256 index) public returns (uint256) {\n return ids[index];\n }\n\n function getData(uint256 index) public returns (uint256 x, uint256 y) {\n x = data[index].x;\n y = data[index].y;\n }\n\n function getLengths() public returns (uint256 l1, uint256 l2) {\n l1 = data.length;\n l2 = ids.length;\n }\n}\n// ----\n// setIDStatic(uint256): 0xb ->\n// getID(uint256): 0x2 -> 0xb\n// setID(uint256,uint256): 0x7, 0x8 ->\n// getID(uint256): 0x7 -> 0x8\n// setData(uint256,uint256,uint256): 0x7, 0x8, 0x9 ->\n// setData(uint256,uint256,uint256): 0x8, 0xa, 0xb ->\n// getData(uint256): 0x7 -> 0x8, 0x9\n// getData(uint256): 0x8 -> 0xa, 0xb\n// getLengths() -> 0x400, 0x403\n" + }, + "bytes_to_fixed_bytes_cleanup.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefg\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n assembly { mstore(m, 14) }\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[0:6]);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdef\\0\\0\"\n// fromCalldata(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdefghabcdefg\\0\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefg\\0\"\n// fromSlice(bytes): 0x20, 15, \"abcdefghabcdefgh\" -> \"abcdef\\0\\0\"\n" + }, + "function_array_cross_calls.sol": { + "content": "contract D {\n function f(function() external returns (function() external returns (uint))[] memory x)\n public returns (function() external returns (uint)[3] memory r) {\n r[0] = x[0]();\n r[1] = x[1]();\n r[2] = x[2]();\n }\n}\n\n\ncontract C {\n function test() public returns (uint256, uint256, uint256) {\n function() external returns (function() external returns (uint))[] memory x =\n new function() external returns (function() external returns (uint))[](10);\n for (uint256 i = 0; i < x.length; i++) x[i] = this.h;\n x[0] = this.htwo;\n function() external returns (uint)[3] memory y = (new D()).f(x);\n return (y[0](), y[1](), y[2]());\n }\n\n function e() public returns (uint256) {\n return 5;\n }\n\n function f() public returns (uint256) {\n return 6;\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n uint256 counter;\n\n function h() public returns (function() external returns (uint)) {\n return counter++ == 0 ? this.f : this.g;\n }\n\n function htwo() public returns (function() external returns (uint)) {\n return this.e;\n }\n}\n// ----\n// test() -> 5, 6, 7\n// gas irOptimized: 86484\n// gas irOptimized code: 161200\n// gas legacy: 97551\n// gas legacy code: 342800\n// gas legacyOptimized: 87808\n// gas legacyOptimized code: 193000\n" + }, + "fixed_out_of_bounds_array_access.sol": { + "content": "contract c {\n uint256[4] data;\n\n function set(uint256 index, uint256 value) public returns (bool) {\n data[index] = value;\n return true;\n }\n\n function get(uint256 index) public returns (uint256) {\n return data[index];\n }\n\n function length() public returns (uint256) {\n return data.length;\n }\n}\n// ----\n// length() -> 4\n// set(uint256,uint256): 3, 4 -> true\n// set(uint256,uint256): 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// set(uint256,uint256): 400, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 3 -> 4\n// get(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x32\n// get(uint256): 400 -> FAILURE, hex\"4e487b71\", 0x32\n// length() -> 4\n" + }, + "fixed_arrays_as_return_type.sol": { + "content": "contract A {\n function f(uint16 input) public pure returns (uint16[5] memory arr) {\n arr[0] = input;\n arr[1] = ++input;\n arr[2] = ++input;\n arr[3] = ++input;\n arr[4] = ++input;\n }\n}\n\n\ncontract B {\n function f() public returns (uint16[5] memory res, uint16[5] memory res2) {\n A a = new A();\n res = a.f(2);\n res2 = a.f(1000);\n }\n}\n// ----\n// f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004\n// gas irOptimized: 59212\n// gas irOptimized code: 56600\n// gas legacy: 68001\n// gas legacy code: 162000\n// gas legacyOptimized: 59997\n// gas legacyOptimized code: 70600\n" + }, + "calldata_array_two_dimensional.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][2] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][2] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][2] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][2]): 0x20, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][2],uint256): 0x40, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][2],uint256): 0x40, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][2],uint256,uint256): 0x60, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 0, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 1, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][2],uint256,uint256): 0x60, 1, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][2],uint256,uint256): 0x60, 0, 3, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256,uint256): 0x60, 1, 4, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][2],uint256): 0x40, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[2] calldata s)\n external\n pure\n returns (uint256 a, uint256 b)\n {\n a = s[0];\n b = s[1];\n }\n}\n// ----\n// f(uint256[2]): 42, 23 -> 42, 23\n" + }, + "inline_array_strings_from_document.sol": { + "content": "contract C {\n function f(uint256 i) public returns (string memory) {\n string[4] memory x = [\"This\", \"is\", \"an\", \"array\"];\n return (x[i]);\n }\n}\n// ----\n// f(uint256): 0 -> 0x20, 0x4, \"This\"\n// f(uint256): 1 -> 0x20, 0x2, \"is\"\n// f(uint256): 2 -> 0x20, 0x2, \"an\"\n// f(uint256): 3 -> 0x20, 0x5, \"array\"\n" + }, + "array_function_pointers.sol": { + "content": "contract C {\n\tfunction f(uint n, uint m) public {\n\t\tfunction() internal returns (uint)[] memory arr = new function() internal returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction f2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() internal returns (uint)[][] memory arr = new function() internal returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() internal returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n\tfunction g(uint n, uint m) public {\n\t\tfunction() external returns (uint)[] memory arr = new function() external returns (uint)[](n);\n\t\tarr[m]();\n\t}\n\tfunction g2(uint n, uint m, uint a, uint b) public {\n\t\tfunction() external returns (uint)[][] memory arr = new function() external returns (uint)[][](n);\n\t\tfor (uint i = 0; i < n; ++i)\n\t\t\tarr[i] = new function() external returns (uint)[](m);\n\t\tarr[a][b]();\n\t}\n}\n// ----\n// f(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// f2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n// g(uint256,uint256): 1823621, 12323 -> FAILURE # Out of gas #\n// g2(uint256,uint256,uint256,uint256): 18723921, 1823621, 123, 12323 -> FAILURE # Out of gas #\n" + }, + "memory_arrays_of_various_sizes.sol": { + "content": "// Computes binomial coefficients the chinese way\ncontract C {\n function f(uint256 n, uint256 k) public returns (uint256) {\n uint256[][] memory rows = new uint256[][](n + 1);\n for (uint256 i = 1; i <= n; i++) {\n rows[i] = new uint256[](i);\n rows[i][0] = rows[i][rows[i].length - 1] = 1;\n for (uint256 j = 1; j < i - 1; j++)\n rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j];\n }\n return rows[n][k - 1];\n }\n}\n// ----\n// f(uint256,uint256): 3, 1 -> 1\n// f(uint256,uint256): 9, 5 -> 70\n" + }, + "array_memory_as_parameter.sol": { + "content": "contract C {\n\tfunction test(uint256 len, uint idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\tuint result = receiver(array, idx);\n\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\trequire(array[i] == i + 1);\n\n\t\treturn result;\n\t}\n\tfunction receiver(uint[] memory array, uint idx) public returns (uint256)\n\t{\n\t\tfor (uint256 i = 0; i < array.length; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[idx];\n\t}\n}\n// ----\n// test(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256,uint256): 1, 0 -> 1\n// test(uint256,uint256): 10, 5 -> 6\n// test(uint256,uint256): 10, 50 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "inline_array_storage_to_memory_conversion_strings.sol": { + "content": "contract C {\n string s = \"doh\";\n\n function f() public returns (string memory, string memory) {\n string memory t = \"ray\";\n string[3] memory x = [s, t, \"mi\"];\n return (x[1], x[2]);\n }\n}\n// ----\n// f() -> 0x40, 0x80, 0x3, \"ray\", 0x2, \"mi\"\n" + }, + "create_memory_array.sol": { + "content": "contract C {\n struct S {\n uint256[2] a;\n bytes b;\n }\n\n function f() public returns (bytes1, uint256, uint256, bytes1) {\n bytes memory x = new bytes(200);\n x[199] = \"A\";\n uint256[2][] memory y = new uint256[2][](300);\n y[203][1] = 8;\n S[] memory z = new S[](180);\n z[170].a[1] = 4;\n z[170].b = new bytes(102);\n z[170].b[99] = \"B\";\n return (x[199], y[203][1], z[170].a[1], z[170].b[99]);\n }\n}\n// ----\n// f() -> \"A\", 8, 4, \"B\"\n// gas irOptimized: 136664\n// gas legacy: 121380\n// gas legacyOptimized: 115488\n" + }, + "byte_array_transitional_2.sol": { + "content": "// Tests transition between short and long encoding both ways\ncontract c {\n bytes data;\n\n function test() public returns (uint256) {\n for (uint8 i = 0; i < 33; i++) {\n data.push(bytes1(i));\n }\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n data.pop();\n data.pop();\n for (uint8 i = 0; i < data.length; i++)\n if (data[i] != bytes1(i)) return i;\n return 0;\n }\n}\n// ----\n// test() -> 0\n// gas irOptimized: 122717\n// gas legacy: 147108\n// gas legacyOptimized: 144200\n" + }, + "fixed_bytes_length_access.sol": { + "content": "contract C {\n bytes1 a;\n\n function f(bytes32 x) public returns (uint256, uint256, uint256) {\n return (x.length, bytes16(uint128(2)).length, a.length + 7);\n }\n}\n// ----\n// f(bytes32): \"789\" -> 32, 16, 8\n" + }, + "array_storage_push_empty.sol": { + "content": "contract C {\n uint256[] storageArray;\n function pushEmpty(uint256 len) public {\n while(storageArray.length < len)\n storageArray.push();\n\n for (uint i = 0; i < len; i++)\n require(storageArray[i] == 0);\n }\n}\n// ====\n// EVMVersion: >=petersburg\n// ----\n// pushEmpty(uint256): 128\n// gas irOptimized: 410745\n// gas legacy: 400519\n// gas legacyOptimized: 388804\n// pushEmpty(uint256): 256\n// gas irOptimized: 698285\n// gas legacy: 684859\n// gas legacyOptimized: 671480\n// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas #\n// gas irOptimized: 100000000\n// gas legacy: 100000000\n// gas legacyOptimized: 100000000\n" + }, + "array_3d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\ta[1][1][1] = n;\n\t\tuint[][] memory b = a[1];\n\t\tuint[] memory c = b[1];\n\t\treturn c[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_memory_create.sol": { + "content": "contract C {\n\tfunction create(uint256 len) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\t\treturn array.length;\n\t}\n}\n// ----\n// create(uint256): 0 -> 0\n// create(uint256): 7 -> 7\n// create(uint256): 10 -> 10\n" + }, + "fixed_arrays_in_constructors.sol": { + "content": "contract Creator {\n uint256 public r;\n address public ch;\n\n constructor(address[3] memory s, uint256 x) {\n r = x;\n ch = s[2];\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 104102\n// gas irOptimized code: 22400\n// gas legacy: 115185\n// gas legacy code: 59000\n// gas legacyOptimized: 104908\n// gas legacyOptimized code: 23800\n// r() -> 4\n// ch() -> 3\n" + }, + "array_storage_index_boundary_test.sol": { + "content": "contract C {\n uint[] storageArray;\n function test_boundary_check(uint256 len, uint256 access) public returns (uint256)\n {\n while(storageArray.length < len)\n storageArray.push();\n while(storageArray.length > len)\n storageArray.pop();\n return storageArray[access];\n }\n}\n// ----\n// test_boundary_check(uint256,uint256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 9 -> 0\n// test_boundary_check(uint256,uint256): 1, 9 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex\"4e487b71\", 0x32\n// gas irOptimized: 147246\n// gas legacy: 133632\n// gas legacyOptimized: 114353\n// test_boundary_check(uint256,uint256): 256, 255 -> 0\n// gas irOptimized: 149422\n// gas legacy: 135948\n// gas legacyOptimized: 116532\n// test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex\"4e487b71\", 0x32\n// test_boundary_check(uint256,uint256): 256, 2 -> 0\n" + }, + "array_2d_assignment.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\ta[1][1] = n;\n\t\tuint[] memory b = a[1];\n\t\treturn b[1];\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_array_cleanup.sol": { + "content": "contract c {\n uint[20] spacer;\n uint[] dynamic;\n function fill() public {\n for (uint i = 0; i < 21; ++i)\n dynamic.push(i + 1);\n }\n function halfClear() public {\n while (dynamic.length > 5)\n dynamic.pop();\n }\n function fullClear() public { delete dynamic; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 519494\n// gas legacy: 518943\n// gas legacyOptimized: 515555\n// storageEmpty -> 0\n// halfClear() ->\n// gas irOptimized: 113961\n// gas legacy: 113257\n// gas legacyOptimized: 113120\n// storageEmpty -> 0\n// fullClear() ->\n// storageEmpty -> 1\n" + }, + "bytes_to_fixed_bytes_simple.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefgh\";\n bytes sLong = \"abcdefghabcdefghabcdefghabcdefgh\";\n\n function fromMemory(bytes memory m) public returns (bytes16) {\n return bytes16(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes16) {\n return bytes16(c);\n }\n function fromStorage() external returns (bytes16) {\n return bytes16(s);\n }\n function fromStorageLong() external returns (bytes32) {\n return bytes32(sLong);\n }\n function fromSlice(bytes calldata c) external returns (bytes8) {\n return bytes8(c[1:9]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"abcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefgh\"\n// fromStorageLong() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 16, \"abcdefghabcdefgh\" -> \"bcdefgha\"\n" + }, + "external_array_args.sol": { + "content": "contract c {\n function test(uint[8] calldata a, uint[] calldata b, uint[5] calldata c, uint a_index, uint b_index, uint c_index)\n external returns (uint av, uint bv, uint cv) {\n av = a[a_index];\n bv = b[b_index];\n cv = c[c_index];\n }\n}\n// ----\n// test(uint256[8],uint256[],uint256[5],uint256,uint256,uint256): 1, 2, 3, 4, 5, 6, 7, 8, 0x220, 21, 22, 23, 24, 25, 0, 1, 2, 3, 11, 12, 13 -> 1, 12, 23\n" + }, + "string_bytes_conversion.sol": { + "content": "contract Test {\n string s;\n bytes b;\n\n function f(string memory _s, uint256 n) public returns (bytes1) {\n b = bytes(_s);\n s = string(b);\n return bytes(s)[n];\n }\n\n function l() public returns (uint256) {\n return bytes(s).length;\n }\n}\n// ----\n// f(string,uint256): 0x40, 0x02, 0x06, \"abcdef\" -> \"c\"\n// l() -> 0x06\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes.sol b/examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes.sol new file mode 100644 index 00000000..dfabd26c --- /dev/null +++ b/examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes.sol @@ -0,0 +1,20 @@ +contract C { + bytes public s = "abc"; + bytes public s1 = "abcd"; + function f() public { + s = "abcd"; + s1 = "abc"; + } + function g() public { + (s, s1) = ("abc", "abcd"); + } +} +// ---- +// s() -> 0x20, 3, "abc" +// s1() -> 0x20, 4, "abcd" +// f() -> +// s() -> 0x20, 4, "abcd" +// s1() -> 0x20, 3, "abc" +// g() -> +// s() -> 0x20, 3, "abc" +// s1() -> 0x20, 4, "abcd" diff --git a/examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes_standard_input.json b/examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes_standard_input.json new file mode 100644 index 00000000..86ac1828 --- /dev/null +++ b/examples/test/semanticTests/array_string_literal_assign_to_storage_bytes/string_literal_assign_to_storage_bytes_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/array_strings_in_struct/strings_in_struct.sol b/examples/test/semanticTests/array_strings_in_struct/strings_in_struct.sol new file mode 100644 index 00000000..bacf8dec --- /dev/null +++ b/examples/test/semanticTests/array_strings_in_struct/strings_in_struct.sol @@ -0,0 +1,35 @@ +contract buggystruct { + Buggy public bug; + + struct Buggy { + uint256 first; + uint256 second; + uint256 third; + string last; + } + + constructor() { + bug = Buggy(10, 20, 30, "asdfghjkl"); + } + + function getFirst() public returns (uint256) { + return bug.first; + } + + function getSecond() public returns (uint256) { + return bug.second; + } + + function getThird() public returns (uint256) { + return bug.third; + } + + function getLast() public returns (string memory) { + return bug.last; + } +} +// ---- +// getFirst() -> 0x0a +// getSecond() -> 0x14 +// getThird() -> 0x1e +// getLast() -> 0x20, 0x09, "asdfghjkl" diff --git a/examples/test/semanticTests/array_strings_in_struct/strings_in_struct_standard_input.json b/examples/test/semanticTests/array_strings_in_struct/strings_in_struct_standard_input.json new file mode 100644 index 00000000..36bbcd37 --- /dev/null +++ b/examples/test/semanticTests/array_strings_in_struct/strings_in_struct_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "bytes_to_fixed_bytes_too_long.sol": { + "content": "contract C {\n bytes s = \"abcdefghabcdefghabcdefghabcdefgha\";\n\n function fromMemory(bytes memory m) public returns (bytes32) {\n return bytes32(m);\n }\n function fromCalldata(bytes calldata c) external returns (bytes32) {\n return bytes32(c);\n }\n function fromStorage() external returns (bytes32) {\n return bytes32(s);\n }\n function fromSlice(bytes calldata c) external returns (bytes32) {\n return bytes32(c[0:33]);\n }\n}\n// ----\n// fromMemory(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromCalldata(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromStorage() -> \"abcdefghabcdefghabcdefghabcdefgh\"\n// fromSlice(bytes): 0x20, 33, \"abcdefghabcdefghabcdefghabcdefgh\", \"a\" -> \"abcdefghabcdefghabcdefghabcdefgh\"\n" + }, + "array_2d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][] memory a = new uint[][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t\ta[i] = new uint[](3);\n\t\treturn a[0][0] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "array_3d_new.sol": { + "content": "contract C {\n\tfunction f(uint n) public pure returns (uint) {\n\t\tuint[][][] memory a = new uint[][][](2);\n\t\tfor (uint i = 0; i < 2; ++i)\n\t\t{\n\t\t\ta[i] = new uint[][](3);\n\t\t\tfor (uint j = 0; j < 3; ++j)\n\t\t\t\ta[i][j] = new uint[](4);\n\t\t}\n\t\treturn a[1][1][1] = n;\n\t}\n}\n// ----\n// f(uint256): 42 -> 42\n" + }, + "dynamic_multi_array_cleanup.sol": { + "content": "contract c {\n struct s { uint[][] d; }\n s[] data;\n function fill() public returns (uint) {\n while (data.length < 3)\n data.push();\n while (data[2].d.length < 4)\n data[2].d.push();\n while (data[2].d[3].length < 5)\n data[2].d[3].push();\n data[2].d[3][4] = 8;\n return data[2].d[3][4];\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() -> 8\n// gas irOptimized: 122985\n// gas legacy: 121602\n// gas legacyOptimized: 120589\n// storageEmpty -> 0\n// clear() ->\n// storageEmpty -> 1\n" + }, + "create_multiple_dynamic_arrays.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory x = new uint256[][](42);\n assert(x[0].length == 0);\n x[0] = new uint256[](1);\n x[0][0] = 1;\n assert(x[4].length == 0);\n x[4] = new uint256[](1);\n x[4][0] = 2;\n assert(x[10].length == 0);\n x[10] = new uint256[](1);\n x[10][0] = 44;\n uint256[][] memory y = new uint256[][](24);\n assert(y[0].length == 0);\n y[0] = new uint256[](1);\n y[0][0] = 1;\n assert(y[4].length == 0);\n y[4] = new uint256[](1);\n y[4][0] = 2;\n assert(y[10].length == 0);\n y[10] = new uint256[](1);\n y[10][0] = 88;\n if (\n (x[0][0] == y[0][0]) &&\n (x[4][0] == y[4][0]) &&\n (x[10][0] == 44) &&\n (y[10][0] == 88)\n ) return 7;\n return 0;\n }\n}\n// ----\n// f() -> 7\n" + }, + "reusing_memory.sol": { + "content": "// Invoke some features that use memory and test that they do not interfere with each other.\ncontract Helper {\n uint256 public flag;\n\n constructor(uint256 x) {\n flag = x;\n }\n}\n\n\ncontract Main {\n mapping(uint256 => uint256) map;\n\n function f(uint256 x) public returns (uint256) {\n map[x] = x;\n return\n (new Helper(uint256(keccak256(abi.encodePacked(this.g(map[x]))))))\n .flag();\n }\n\n function g(uint256 a) public returns (uint256) {\n return map[a];\n }\n}\n// ----\n// f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1\n// gas irOptimized: 99552\n// gas irOptimized code: 12400\n// gas legacy: 101551\n// gas legacy code: 23600\n// gas legacyOptimized: 99612\n// gas legacyOptimized code: 13400\n" + }, + "fixed_array_cleanup.sol": { + "content": "contract c {\n uint spacer1;\n uint spacer2;\n uint[20] data;\n function fill() public {\n for (uint i = 0; i < data.length; ++i) data[i] = i+1;\n }\n function clear() public { delete data; }\n}\n// ----\n// storageEmpty -> 1\n// fill() ->\n// gas irOptimized: 465013\n// gas legacy: 468825\n// gas legacyOptimized: 466238\n// storageEmpty -> 0\n// clear() ->\n// gas irOptimized: 122148\n// gas legacy: 122440\n// gas legacyOptimized: 122259\n// storageEmpty -> 1\n" + }, + "create_memory_byte_array.sol": { + "content": "contract C {\n function f() public returns (bytes1) {\n bytes memory x = new bytes(35);\n assert(x.length == 35);\n x[34] = \"A\";\n return (x[34]);\n }\n}\n// ----\n// f() -> \"A\"\n" + }, + "calldata_array_as_argument_internal_function.sol": { + "content": "pragma abicoder v2;\ncontract Test {\n function f(uint256[] calldata c) internal returns (uint a, uint b) {\n return (c.length, c[0]);\n }\n\n function g(uint256[] calldata c) external returns (uint a, uint b) {\n return f(c);\n }\n\n function h(uint256[] calldata c, uint start, uint end) external returns (uint a, uint b) {\n return f(c[start: end]);\n }\n}\n// ----\n// g(uint256[]): 0x20, 4, 1, 2, 3, 4 -> 4, 1\n// h(uint256[],uint256,uint256): 0x60, 1, 3, 4, 1, 2, 3, 4 -> 2, 2\n" + }, + "calldata_array_dynamic_invalid_static_middle.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][1][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][1][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n\n function h(uint256[][1][] calldata a) external returns (uint256) {\n a[0][0];\n return 42;\n }\n}\n// ----\n// f(uint256[][1][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][1][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][1][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42 # invalid on inner access #\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20 -> FAILURE\n// f(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// g(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> 42\n// h(uint256[][1][]): 0x20, 0x1, 0x20, 0x20, 0x1 -> FAILURE\n" + }, + "calldata_array_two_dimensional_1.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function test(uint256[][] calldata a) external returns (uint256) {\n return a.length;\n }\n function test(uint256[][] calldata a, uint256 i) external returns (uint256) {\n return a[i].length;\n }\n function test(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return a[i][j];\n }\n function reenc(uint256[][] calldata a, uint256 i, uint256 j) external returns (uint256) {\n return this.test(a, i, j);\n }\n}\n// ----\n// test(uint256[][]): 0x20, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 2\n// test(uint256[][],uint256): 0x40, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 3\n// test(uint256[][],uint256): 0x40, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 4\n// test(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A01\n// test(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A02\n// test(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// reenc(uint256[][],uint256,uint256): 0x60, 0, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0A03\n// test(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 0, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B01\n// test(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 1, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B02\n// test(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B03\n// test(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// reenc(uint256[][],uint256,uint256): 0x60, 1, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> 0x0B04\n// test(uint256[][],uint256,uint256): 0x60, 0, 3, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256,uint256): 0x60, 1, 4, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256[][],uint256): 0x40, 2, 2, 0x40, 0xC0, 3, 0x0A01, 0x0A02, 0x0A03, 4, 0x0B01, 0x0B02, 0x0B03, 0x0B04 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_return_reference.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push() = v;\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, 0x6162000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "array_push_with_arg.sol": { + "content": "contract C {\n uint[] storageArray;\n function test(uint256 v) public {\n storageArray.push(v);\n }\n function getLength() public view returns (uint256) {\n return storageArray.length;\n }\n function fetch(uint256 a) public view returns (uint256) {\n return storageArray[a];\n }\n}\n// ----\n// getLength() -> 0\n// test(uint256): 42 ->\n// getLength() -> 1\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x32\n// test(uint256): 23 ->\n// getLength() -> 2\n// fetch(uint256): 0 -> 42\n// fetch(uint256): 1 -> 23\n// fetch(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_of_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S[] calldata s)\n external\n pure\n returns (uint256 l, uint256 a, uint256 b, uint256 c, uint256 d)\n {\n l = s.length;\n a = s[0].a;\n b = s[0].b;\n c = s[1].a;\n d = s[1].b;\n }\n}\n// ----\n// f((uint256,uint256)[]): 0x20, 0x2, 0x1, 0x2, 0x3, 0x4 -> 2, 1, 2, 3, 4\n" + }, + "string_allocation_bug.sol": { + "content": "contract Sample {\n struct s {\n uint16 x;\n uint16 y;\n string a;\n string b;\n }\n s[2] public p;\n\n constructor() {\n s memory m;\n m.x = 0xbbbb;\n m.y = 0xcccc;\n m.a = \"hello\";\n m.b = \"world\";\n p[0] = m;\n }\n}\n// ----\n// p(uint256): 0x0 -> 0xbbbb, 0xcccc, 0x80, 0xc0, 0x05, \"hello\", 0x05, \"world\"\n" + }, + "array_memory_index_access.sol": { + "content": "contract C {\n\tfunction index(uint256 len) public returns (bool)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\trequire(array[i] == i + 1, \"Unexpected value in array!\");\n\n\t\treturn array.length == len;\n\t}\n\tfunction accessIndex(uint256 len, int256 idx) public returns (uint256)\n\t{\n\t\tuint[] memory array = new uint[](len);\n\n\t\tfor (uint256 i = 0; i < len; i++)\n\t\t\tarray[i] = i + 1;\n\n\t\treturn array[uint256(idx)];\n\t}\n}\n// ----\n// index(uint256): 0 -> true\n// index(uint256): 10 -> true\n// index(uint256): 20 -> true\n// index(uint256): 0xFF -> true\n// gas irOptimized: 108272\n// gas legacy: 181536\n// gas legacyOptimized: 117442\n// accessIndex(uint256,int256): 10, 1 -> 2\n// accessIndex(uint256,int256): 10, 0 -> 1\n// accessIndex(uint256,int256): 10, 11 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, 10 -> FAILURE, hex\"4e487b71\", 0x32\n// accessIndex(uint256,int256): 10, -1 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint256[][] calldata a) external returns (uint256) {\n return 42;\n }\n\n function g(uint256[][] calldata a) external returns (uint256) {\n a[0];\n return 42;\n }\n}\n// ----\n// f(uint256[][]): 0x20, 0x0 -> 42 # valid access stub #\n// f(uint256[][]): 0x20, 0x1 -> FAILURE # invalid on argument decoding #\n// f(uint256[][]): 0x20, 0x1, 0x20 -> 42 # invalid on outer access #\n// g(uint256[][]): 0x20, 0x1, 0x20 -> FAILURE\n// f(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> 42 # invalid on inner access #\n// g(uint256[][]): 0x20, 0x1, 0x20, 0x2, 0x42 -> FAILURE\n" + }, + "evm_exceptions_out_of_band_access.sol": { + "content": "contract A {\n uint256[3] arr;\n bool public test = false;\n\n function getElement(uint256 i) public returns (uint256) {\n return arr[i];\n }\n\n function testIt() public returns (bool) {\n uint256 i = this.getElement(5);\n test = true;\n return true;\n }\n}\n// ----\n// test() -> false\n// testIt() -> FAILURE, hex\"4e487b71\", 0x32\n// test() -> false\n" + }, + "string_literal_assign_to_storage_bytes.sol": { + "content": "contract C {\n bytes public s = \"abc\";\n bytes public s1 = \"abcd\";\n function f() public {\n s = \"abcd\";\n s1 = \"abc\";\n }\n function g() public {\n (s, s1) = (\"abc\", \"abcd\");\n }\n}\n// ----\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n// f() ->\n// s() -> 0x20, 4, \"abcd\"\n// s1() -> 0x20, 3, \"abc\"\n// g() ->\n// s() -> 0x20, 3, \"abc\"\n// s1() -> 0x20, 4, \"abcd\"\n" + }, + "create_dynamic_array_with_zero_length.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256[][] memory a = new uint256[][](0);\n return 7;\n }\n}\n// ----\n// f() -> 7\n" + }, + "strings_in_struct.sol": { + "content": "contract buggystruct {\n Buggy public bug;\n\n struct Buggy {\n uint256 first;\n uint256 second;\n uint256 third;\n string last;\n }\n\n constructor() {\n bug = Buggy(10, 20, 30, \"asdfghjkl\");\n }\n\n function getFirst() public returns (uint256) {\n return bug.first;\n }\n\n function getSecond() public returns (uint256) {\n return bug.second;\n }\n\n function getThird() public returns (uint256) {\n return bug.third;\n }\n\n function getLast() public returns (string memory) {\n return bug.last;\n }\n}\n// ----\n// getFirst() -> 0x0a\n// getSecond() -> 0x14\n// getThird() -> 0x1e\n// getLast() -> 0x20, 0x09, \"asdfghjkl\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break.sol b/examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break.sol new file mode 100644 index 00000000..d74db942 --- /dev/null +++ b/examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break.sol @@ -0,0 +1,13 @@ +contract C { + function f() public returns (uint i) { + assembly { + for {} lt(i, 10) { i := add(i, 1) } + { + if eq(i, 6) { break } + i := add(i, 1) + } + } + } +} +// ---- +// f() -> 6 diff --git a/examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break_standard_input.json b/examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break_standard_input.json new file mode 100644 index 00000000..da2a32fc --- /dev/null +++ b/examples/test/semanticTests/asmForLoop_for_loop_break/for_loop_break_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "for_loop_continue.sol": { + "content": "contract C {\n function f() public returns (uint k) {\n assembly {\n for {let i := 0} lt(i, 10) { i := add(i, 1) }\n {\n if eq(mod(i, 2), 0) { continue }\n k := add(k, 1)\n }\n }\n }\n}\n// ----\n// f() -> 5\n" + }, + "for_loop_break.sol": { + "content": "contract C {\n function f() public returns (uint i) {\n assembly {\n for {} lt(i, 10) { i := add(i, 1) }\n {\n if eq(i, 6) { break }\n i := add(i, 1)\n }\n }\n }\n}\n// ----\n// f() -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue.sol b/examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue.sol new file mode 100644 index 00000000..f25a3c06 --- /dev/null +++ b/examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue.sol @@ -0,0 +1,13 @@ +contract C { + function f() public returns (uint k) { + assembly { + for {let i := 0} lt(i, 10) { i := add(i, 1) } + { + if eq(mod(i, 2), 0) { continue } + k := add(k, 1) + } + } + } +} +// ---- +// f() -> 5 diff --git a/examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue_standard_input.json b/examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue_standard_input.json new file mode 100644 index 00000000..97bfb20d --- /dev/null +++ b/examples/test/semanticTests/asmForLoop_for_loop_continue/for_loop_continue_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "for_loop_continue.sol": { + "content": "contract C {\n function f() public returns (uint k) {\n assembly {\n for {let i := 0} lt(i, 10) { i := add(i, 1) }\n {\n if eq(mod(i, 2), 0) { continue }\n k := add(k, 1)\n }\n }\n }\n}\n// ----\n// f() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested.sol b/examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested.sol new file mode 100644 index 00000000..3a13e9f0 --- /dev/null +++ b/examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested.sol @@ -0,0 +1,20 @@ +contract C { + function f(uint x) public returns (uint i) { + assembly { + for {} lt(i, 10) { i := add(i, 1) } + { + if eq(x, 0) { i := 2 break } + for {} lt(x, 3) { i := 17 x := 9 } { + if eq(x, 1) { continue } + if eq(x, 2) { break } + } + if eq(x, 4) { i := 90 } + } + } + } +} +// ---- +// f(uint256): 0 -> 2 +// f(uint256): 1 -> 18 +// f(uint256): 2 -> 10 +// f(uint256): 4 -> 91 diff --git a/examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested_standard_input.json b/examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested_standard_input.json new file mode 100644 index 00000000..41f46f39 --- /dev/null +++ b/examples/test/semanticTests/asmForLoop_for_loop_nested/for_loop_nested_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "for_loop_continue.sol": { + "content": "contract C {\n function f() public returns (uint k) {\n assembly {\n for {let i := 0} lt(i, 10) { i := add(i, 1) }\n {\n if eq(mod(i, 2), 0) { continue }\n k := add(k, 1)\n }\n }\n }\n}\n// ----\n// f() -> 5\n" + }, + "for_loop_break.sol": { + "content": "contract C {\n function f() public returns (uint i) {\n assembly {\n for {} lt(i, 10) { i := add(i, 1) }\n {\n if eq(i, 6) { break }\n i := add(i, 1)\n }\n }\n }\n}\n// ----\n// f() -> 6\n" + }, + "for_loop_nested.sol": { + "content": "contract C {\n function f(uint x) public returns (uint i) {\n assembly {\n for {} lt(i, 10) { i := add(i, 1) }\n {\n if eq(x, 0) { i := 2 break }\n for {} lt(x, 3) { i := 17 x := 9 } {\n if eq(x, 1) { continue }\n if eq(x, 2) { break }\n }\n if eq(x, 4) { i := 90 }\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 18\n// f(uint256): 2 -> 10\n// f(uint256): 4 -> 91\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak.sol b/examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak.sol new file mode 100644 index 00000000..2fc479d0 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak.sol @@ -0,0 +1,9 @@ +contract C { + bytes32 constant x = keccak256("abc"); + + function f() public returns (bytes32) { + return x; + } +} +// ---- +// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 diff --git a/examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak_standard_input.json b/examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak_standard_input.json new file mode 100644 index 00000000..34715429 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_assignment_to_const_var_involving_keccak/assignment_to_const_var_involving_keccak_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_blobhash/blobhash.sol b/examples/test/semanticTests/builtinFunctions_blobhash/blobhash.sol new file mode 100644 index 00000000..445a011b --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blobhash/blobhash.sol @@ -0,0 +1,18 @@ +contract C { + function f() public view returns(bytes32) { + return blobhash(0); + } + function g() public view returns(bytes32) { + return blobhash(1); + } + function h() public view returns(bytes32) { + // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed. + return blobhash(2); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001 +// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002 +// h() -> 0x00 diff --git a/examples/test/semanticTests/builtinFunctions_blobhash/blobhash_standard_input.json b/examples/test/semanticTests/builtinFunctions_blobhash/blobhash_standard_input.json new file mode 100644 index 00000000..ca2316e9 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blobhash/blobhash_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + }, + "keccak256_multiple_arguments_with_numeric_literals.sol": { + "content": "contract c {\n function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145)));\n }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns(bytes32) {\n return blobhash(0);\n }\n function g() public view returns(bytes32) {\n return blobhash(1);\n }\n function h() public view returns(bytes32) {\n // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed.\n return blobhash(2);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// h() -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution.sol b/examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution.sol new file mode 100644 index 00000000..6a141cb9 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution.sol @@ -0,0 +1,12 @@ +contract C { + function blobhash(uint256 index) public pure returns(bytes32) { + return bytes32(index); + } + function f() public pure returns(bytes32) { + return blobhash(3); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0x03 diff --git a/examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution_standard_input.json b/examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution_standard_input.json new file mode 100644 index 00000000..9ddbf7be --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blobhash_shadow_resolution/blobhash_shadow_resolution_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_blockhash/blockhash.sol b/examples/test/semanticTests/builtinFunctions_blockhash/blockhash.sol new file mode 100644 index 00000000..008a0467 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blockhash/blockhash.sol @@ -0,0 +1,15 @@ +contract C { + function f() public returns(bytes32) { + return blockhash(1); + } + function g() public returns(bytes32) { + return blockhash(2); + } + function h() public returns(bytes32) { + return blockhash(3); + } +} +// ---- +// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738 +// g() -> 0x3737373737373737373737373737373737373737373737373737373737373739 +// h() -> 0x373737373737373737373737373737373737373737373737373737373737373a diff --git a/examples/test/semanticTests/builtinFunctions_blockhash/blockhash_standard_input.json b/examples/test/semanticTests/builtinFunctions_blockhash/blockhash_standard_input.json new file mode 100644 index 00000000..70398278 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blockhash/blockhash_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + }, + "keccak256_multiple_arguments_with_numeric_literals.sol": { + "content": "contract c {\n function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145)));\n }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns(bytes32) {\n return blobhash(0);\n }\n function g() public view returns(bytes32) {\n return blobhash(1);\n }\n function h() public view returns(bytes32) {\n // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed.\n return blobhash(2);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// h() -> 0x00\n" + }, + "function_types_sig.sol": { + "content": "contract C {\n uint256 public x;\n\n function f() public pure returns (bytes4) {\n return this.f.selector;\n }\n\n function g() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function h() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function i() public pure returns (bytes4) {\n return this.x.selector;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash.sol": { + "content": "contract C {\n function f() public returns(bytes32) {\n return blockhash(1);\n }\n function g() public returns(bytes32) {\n return blockhash(2);\n }\n function h() public returns(bytes32) {\n return blockhash(3);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// g() -> 0x3737373737373737373737373737373737373737373737373737373737373739\n// h() -> 0x373737373737373737373737373737373737373737373737373737373737373a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution.sol b/examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution.sol new file mode 100644 index 00000000..0b532da0 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution.sol @@ -0,0 +1,6 @@ +contract C { + function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; } + function f() public returns(bytes32) { return blockhash(3); } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution_standard_input.json b/examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution_standard_input.json new file mode 100644 index 00000000..34dd0e68 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_blockhash_shadow_resolution/blockhash_shadow_resolution_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig.sol b/examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig.sol new file mode 100644 index 00000000..2e771032 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig.sol @@ -0,0 +1,26 @@ +contract C { + uint256 public x; + + function f() public pure returns (bytes4) { + return this.f.selector; + } + + function g() public returns (bytes4) { + function () pure external returns (bytes4) fun = this.f; + return fun.selector; + } + + function h() public returns (bytes4) { + function () pure external returns (bytes4) fun = this.f; + return fun.selector; + } + + function i() public pure returns (bytes4) { + return this.x.selector; + } +} +// ---- +// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000 +// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000 +// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000 +// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig_standard_input.json b/examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig_standard_input.json new file mode 100644 index 00000000..7e13639e --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_function_types_sig/function_types_sig_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + }, + "keccak256_multiple_arguments_with_numeric_literals.sol": { + "content": "contract c {\n function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145)));\n }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns(bytes32) {\n return blobhash(0);\n }\n function g() public view returns(bytes32) {\n return blobhash(1);\n }\n function h() public view returns(bytes32) {\n // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed.\n return blobhash(2);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// h() -> 0x00\n" + }, + "function_types_sig.sol": { + "content": "contract C {\n uint256 public x;\n\n function f() public pure returns (bytes4) {\n return this.f.selector;\n }\n\n function g() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function h() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function i() public pure returns (bytes4) {\n return this.x.selector;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes.sol b/examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes.sol new file mode 100644 index 00000000..91a26945 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes.sol @@ -0,0 +1,12 @@ +contract c { + bytes data; + + function foo() public returns (bytes32) { + data.push("x"); + data.push("y"); + data.push("z"); + return keccak256(abi.encodePacked("b", keccak256(data), "a")); + } +} +// ---- +// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc diff --git a/examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes_standard_input.json b/examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes_standard_input.json new file mode 100644 index 00000000..aedcd8ec --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_iterated_keccak256_with_bytes/iterated_keccak256_with_bytes_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256/keccak256.sol b/examples/test/semanticTests/builtinFunctions_keccak256/keccak256.sol new file mode 100644 index 00000000..e01a5695 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256/keccak256.sol @@ -0,0 +1,9 @@ +contract C { + function f(int256 input) public returns (bytes32 sha256hash) { + return keccak256(abi.encodePacked(bytes32(uint256(input)))); + } +} +// ---- +// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b +// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0 +// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9 diff --git a/examples/test/semanticTests/builtinFunctions_keccak256/keccak256_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256/keccak256_standard_input.json new file mode 100644 index 00000000..747d49c3 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256/keccak256_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty.sol b/examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty.sol new file mode 100644 index 00000000..f75c569e --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (bytes32) { + return keccak256(""); + } +} +// ---- +// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty_standard_input.json new file mode 100644 index 00000000..7b69931e --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_empty/keccak256_empty_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments.sol b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments.sol new file mode 100644 index 00000000..972aee83 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments.sol @@ -0,0 +1,7 @@ +contract c { + function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) { + d = keccak256(abi.encodePacked(a, b, c)); + } +} +// ---- +// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81 diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments_standard_input.json new file mode 100644 index 00000000..f415cf97 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments/keccak256_multiple_arguments_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals.sol b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals.sol new file mode 100644 index 00000000..01397f55 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals.sol @@ -0,0 +1,7 @@ +contract c { + function foo(uint256 a, uint16 b) public returns (bytes32 d) { + d = keccak256(abi.encodePacked(a, b, uint8(145))); + } +} +// ---- +// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals_standard_input.json new file mode 100644 index 00000000..a9db95a9 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_numeric_literals/keccak256_multiple_arguments_with_numeric_literals_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + }, + "keccak256_multiple_arguments_with_numeric_literals.sol": { + "content": "contract c {\n function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145)));\n }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals.sol b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals.sol new file mode 100644 index 00000000..b157178f --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals.sol @@ -0,0 +1,12 @@ +contract c { + function foo() public returns (bytes32 d) { + d = keccak256("foo"); + } + + function bar(uint256 a, uint16 b) public returns (bytes32 d) { + d = keccak256(abi.encodePacked(a, b, uint8(145), "foo")); + } +} +// ---- +// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d +// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146 diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals_standard_input.json new file mode 100644 index 00000000..771b0044 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_multiple_arguments_with_string_literals/keccak256_multiple_arguments_with_string_literals_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed.sol b/examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed.sol new file mode 100644 index 00000000..cad49dae --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed.sol @@ -0,0 +1,12 @@ +contract C { + function f(int256 _input) public returns (bytes32 hash) { + uint24 b = 65536; + uint c = 256; + bytes32 input = bytes32(uint256(_input)); + return keccak256(abi.encodePacked(uint8(8), input, b, input, c)); + } +} +// ---- +// f(int256): 4 -> 0xd270285b9966fefc715561efcd09d5b6a8deb15596f7c53cb4a1bb73aa55ac3a +// f(int256): 5 -> 0xf2f92566c5653600c1e527a7073e5d881576d12bb51887c0b8f3e1f81865b03d +// f(int256): -1 -> 0xbc78b45e0db67af5af72e4ab62757c67aefa7388cdf0c4e74f8b5fe9dd5d9d13 diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed_standard_input.json new file mode 100644 index 00000000..279e6b18 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_packed/keccak256_packed_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + }, + "keccak256_multiple_arguments_with_numeric_literals.sol": { + "content": "contract c {\n function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145)));\n }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns(bytes32) {\n return blobhash(0);\n }\n function g() public view returns(bytes32) {\n return blobhash(1);\n }\n function h() public view returns(bytes32) {\n // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed.\n return blobhash(2);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// h() -> 0x00\n" + }, + "function_types_sig.sol": { + "content": "contract C {\n uint256 public x;\n\n function f() public pure returns (bytes4) {\n return this.f.selector;\n }\n\n function g() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function h() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function i() public pure returns (bytes4) {\n return this.x.selector;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash.sol": { + "content": "contract C {\n function f() public returns(bytes32) {\n return blockhash(1);\n }\n function g() public returns(bytes32) {\n return blockhash(2);\n }\n function h() public returns(bytes32) {\n return blockhash(3);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// g() -> 0x3737373737373737373737373737373737373737373737373737373737373739\n// h() -> 0x373737373737373737373737373737373737373737373737373737373737373a\n" + }, + "keccak256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return keccak256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xd270285b9966fefc715561efcd09d5b6a8deb15596f7c53cb4a1bb73aa55ac3a\n// f(int256): 5 -> 0xf2f92566c5653600c1e527a7073e5d881576d12bb51887c0b8f3e1f81865b03d\n// f(int256): -1 -> 0xbc78b45e0db67af5af72e4ab62757c67aefa7388cdf0c4e74f8b5fe9dd5d9d13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types.sol b/examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types.sol new file mode 100644 index 00000000..ea6d7818 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types.sol @@ -0,0 +1,14 @@ +contract C { + uint120[3] x; + function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) { + uint120[] memory y = new uint120[](3); + x[0] = y[0] = uint120(type(uint).max - 1); + x[1] = y[1] = uint120(type(uint).max - 2); + x[2] = y[2] = uint120(type(uint).max - 3); + hash1 = keccak256(abi.encodePacked(x)); + hash2 = keccak256(abi.encodePacked(y)); + hash3 = keccak256(abi.encodePacked(this.f)); + } +} +// ---- +// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types_standard_input.json new file mode 100644 index 00000000..b5bc3da4 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_packed_complex_types/keccak256_packed_complex_types_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes.sol b/examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes.sol new file mode 100644 index 00000000..1904e814 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes.sol @@ -0,0 +1,12 @@ +contract c { + bytes data; + + function foo() public returns (bool) { + data.push("f"); + data.push("o"); + data.push("o"); + return keccak256(data) == keccak256("foo"); + } +} +// ---- +// foo() -> true diff --git a/examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes_standard_input.json b/examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes_standard_input.json new file mode 100644 index 00000000..d1c0853e --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_keccak256_with_bytes/keccak256_with_bytes_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig.sol b/examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig.sol new file mode 100644 index 00000000..f28658fe --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig.sol @@ -0,0 +1,7 @@ +contract test { + function foo(uint256 a) public returns (bytes4 value) { + return msg.sig; + } +} +// ---- +// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig_standard_input.json b/examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig_standard_input.json new file mode 100644 index 00000000..4881ada4 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_msg_sig/msg_sig_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same.sol b/examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same.sol new file mode 100644 index 00000000..7ff53efa --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same.sol @@ -0,0 +1,11 @@ +contract test { + function boo() public returns (bytes4 value) { + return msg.sig; + } + + function foo(uint256 a) public returns (bytes4 value) { + return boo(); + } +} +// ---- +// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same_standard_input.json b/examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same_standard_input.json new file mode 100644 index 00000000..d01061e4 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_msg_sig_after_internal_call_is_same/msg_sig_after_internal_call_is_same_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + }, + "keccak256_multiple_arguments_with_numeric_literals.sol": { + "content": "contract c {\n function foo(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145)));\n }\n}\n// ----\n// foo(uint256,uint16): 0xa, 0xc -> 0x88acd45f75907e7c560318bc1a5249850a0999c4896717b1167d05d116e6dbad\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns(bytes32) {\n return blobhash(0);\n }\n function g() public view returns(bytes32) {\n return blobhash(1);\n }\n function h() public view returns(bytes32) {\n // NOTE: blobhash(2) should return 0 since EVMHost has only two blob hashes injected in the block the transaction is being executed.\n return blobhash(2);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// g() -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// h() -> 0x00\n" + }, + "function_types_sig.sol": { + "content": "contract C {\n uint256 public x;\n\n function f() public pure returns (bytes4) {\n return this.f.selector;\n }\n\n function g() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function h() public returns (bytes4) {\n function () pure external returns (bytes4) fun = this.f;\n return fun.selector;\n }\n\n function i() public pure returns (bytes4) {\n return this.x.selector;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// i() -> 0x0c55699c00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash.sol": { + "content": "contract C {\n function f() public returns(bytes32) {\n return blockhash(1);\n }\n function g() public returns(bytes32) {\n return blockhash(2);\n }\n function h() public returns(bytes32) {\n return blockhash(3);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// g() -> 0x3737373737373737373737373737373737373737373737373737373737373739\n// h() -> 0x373737373737373737373737373737373737373737373737373737373737373a\n" + }, + "keccak256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return keccak256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xd270285b9966fefc715561efcd09d5b6a8deb15596f7c53cb4a1bb73aa55ac3a\n// f(int256): 5 -> 0xf2f92566c5653600c1e527a7073e5d881576d12bb51887c0b8f3e1f81865b03d\n// f(int256): -1 -> 0xbc78b45e0db67af5af72e4ab62757c67aefa7388cdf0c4e74f8b5fe9dd5d9d13\n" + }, + "msg_sig_after_internal_call_is_same.sol": { + "content": "contract test {\n function boo() public returns (bytes4 value) {\n return msg.sig;\n }\n\n function foo(uint256 a) public returns (bytes4 value) {\n return boo();\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160.sol b/examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160.sol new file mode 100644 index 00000000..e070a65f --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160.sol @@ -0,0 +1,9 @@ +contract C { + function f(int256 input) public returns (bytes32 sha256hash) { + return ripemd160(abi.encodePacked(bytes32(uint256(input)))); + } +} +// ---- +// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000 +// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000 +// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000 diff --git a/examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160_standard_input.json b/examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160_standard_input.json new file mode 100644 index 00000000..b041dc55 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_ripemd160/ripemd160_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty.sol b/examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty.sol new file mode 100644 index 00000000..330fafc4 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (bytes20) { + return ripemd160(""); + } +} +// ---- +// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000 diff --git a/examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty_standard_input.json b/examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty_standard_input.json new file mode 100644 index 00000000..2bc2a633 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_ripemd160_empty/ripemd160_empty_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed.sol b/examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed.sol new file mode 100644 index 00000000..733bd420 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed.sol @@ -0,0 +1,12 @@ +contract C { + function f(int256 _input) public returns (bytes32 hash) { + uint24 b = 65536; + uint c = 256; + bytes32 input = bytes32(uint256(_input)); + return ripemd160(abi.encodePacked(uint8(8), input, b, input, c)); + } +} +// ---- +// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000 +// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000 +// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000 diff --git a/examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed_standard_input.json b/examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed_standard_input.json new file mode 100644 index 00000000..c8c5824a --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_ripemd160_packed/ripemd160_packed_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_sha256/sha256.sol b/examples/test/semanticTests/builtinFunctions_sha256/sha256.sol new file mode 100644 index 00000000..4060a7fa --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_sha256/sha256.sol @@ -0,0 +1,9 @@ +contract C { + function f(int256 input) public returns (bytes32 sha256hash) { + return sha256(abi.encodePacked(bytes32(uint256(input)))); + } +} +// ---- +// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f +// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47 +// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051 diff --git a/examples/test/semanticTests/builtinFunctions_sha256/sha256_standard_input.json b/examples/test/semanticTests/builtinFunctions_sha256/sha256_standard_input.json new file mode 100644 index 00000000..1adb1c10 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_sha256/sha256_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty.sol b/examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty.sol new file mode 100644 index 00000000..bb9fc361 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (bytes32) { + return sha256(""); + } +} +// ---- +// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 diff --git a/examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty_standard_input.json b/examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty_standard_input.json new file mode 100644 index 00000000..f42fae82 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_sha256_empty/sha256_empty_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + }, + "keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bool) {\n data.push(\"f\");\n data.push(\"o\");\n data.push(\"o\");\n return keccak256(data) == keccak256(\"foo\");\n }\n}\n// ----\n// foo() -> true\n" + }, + "blockhash_shadow_resolution.sol": { + "content": "contract C {\n function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }\n function f() public returns(bytes32) { return blockhash(3); }\n}\n// ----\n// f() -> 0\n" + }, + "assignment_to_const_var_involving_keccak.sol": { + "content": "contract C {\n bytes32 constant x = keccak256(\"abc\");\n\n function f() public returns (bytes32) {\n return x;\n }\n}\n// ----\n// f() -> 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n" + }, + "keccak256_multiple_arguments_with_string_literals.sol": { + "content": "contract c {\n function foo() public returns (bytes32 d) {\n d = keccak256(\"foo\");\n }\n\n function bar(uint256 a, uint16 b) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, uint8(145), \"foo\"));\n }\n}\n// ----\n// foo() -> 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d\n// bar(uint256,uint16): 0xa, 0xc -> 0x6990f36476dc412b1c4baa48e2d9f4aa4bb313f61fda367c8fdbbb2232dc6146\n" + }, + "blobhash_shadow_resolution.sol": { + "content": "contract C {\n function blobhash(uint256 index) public pure returns(bytes32) {\n return bytes32(index);\n }\n function f() public pure returns(bytes32) {\n return blobhash(3);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x03\n" + }, + "sha256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return sha256(\"\");\n }\n}\n// ----\n// f() -> 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed.sol b/examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed.sol new file mode 100644 index 00000000..19959c44 --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed.sol @@ -0,0 +1,12 @@ +contract C { + function f(int256 _input) public returns (bytes32 hash) { + uint24 b = 65536; + uint c = 256; + bytes32 input = bytes32(uint256(_input)); + return sha256(abi.encodePacked(uint8(8), input, b, input, c)); + } +} +// ---- +// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac +// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0 +// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7 diff --git a/examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed_standard_input.json b/examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed_standard_input.json new file mode 100644 index 00000000..d35576ca --- /dev/null +++ b/examples/test/semanticTests/builtinFunctions_sha256_packed/sha256_packed_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "keccak256_empty.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return keccak256(\"\");\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "ripemd160_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return ripemd160(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0xf93175303eba2a7b372174fc9330237f5ad202fc000000000000000000000000\n// f(int256): 5 -> 0x04f4fc112e2bfbe0d38f896a46629e08e2fcfad5000000000000000000000000\n// f(int256): -1 -> 0xc0a2e4b1f3ff766a9a0089e7a410391730872495000000000000000000000000\n" + }, + "ripemd160.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return ripemd160(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x1b0f3c404d12075c68c938f9f60ebea4f74941a0000000000000000000000000\n// f(int256): 5 -> 0xee54aa84fc32d8fed5a5fe160442ae84626829d9000000000000000000000000\n// f(int256): -1 -> 0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3000000000000000000000000\n" + }, + "keccak256_packed_complex_types.sol": { + "content": "contract C {\n uint120[3] x;\n function f() public returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {\n uint120[] memory y = new uint120[](3);\n x[0] = y[0] = uint120(type(uint).max - 1);\n x[1] = y[1] = uint120(type(uint).max - 2);\n x[2] = y[2] = uint120(type(uint).max - 3);\n hash1 = keccak256(abi.encodePacked(x));\n hash2 = keccak256(abi.encodePacked(y));\n hash3 = keccak256(abi.encodePacked(this.f));\n }\n}\n// ----\n// f() -> 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0xba4f20407251e4607cd66b90bfea19ec6971699c03e4a4f3ea737d5818ac27ae, 0x0e9229fb1d2cd02cee4b6c9f25497777014a8766e3479666d1c619066d2887ec\n" + }, + "iterated_keccak256_with_bytes.sol": { + "content": "contract c {\n bytes data;\n\n function foo() public returns (bytes32) {\n data.push(\"x\");\n data.push(\"y\");\n data.push(\"z\");\n return keccak256(abi.encodePacked(\"b\", keccak256(data), \"a\"));\n }\n}\n// ----\n// foo() -> 0xb338eefce206f9f57b83aa738deecd5326dc4b72dd81ee6a7c621a6facb7acdc\n" + }, + "keccak256_multiple_arguments.sol": { + "content": "contract c {\n function foo(uint256 a, uint256 b, uint256 c) public returns (bytes32 d) {\n d = keccak256(abi.encodePacked(a, b, c));\n }\n}\n// ----\n// foo(uint256,uint256,uint256): 0xa, 0xc, 0xd -> 0xbc740a98aae5923e8f04c9aa798c9ee82f69e319997699f2782c40828db9fd81\n" + }, + "ripemd160_empty.sol": { + "content": "contract C {\n function f() public returns (bytes20) {\n return ripemd160(\"\");\n }\n}\n// ----\n// f() -> 0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000\n" + }, + "keccak256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return keccak256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b\n// f(int256): 5 -> 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0\n// f(int256): -1 -> 0xa9c584056064687e149968cbab758a3376d22aedc6a55823d1b3ecbee81b8fb9\n" + }, + "msg_sig.sol": { + "content": "contract test {\n function foo(uint256 a) public returns (bytes4 value) {\n return msg.sig;\n }\n}\n// ----\n// foo(uint256): 0x0 -> 0x2fbebd3800000000000000000000000000000000000000000000000000000000\n" + }, + "sha256.sol": { + "content": "contract C {\n function f(int256 input) public returns (bytes32 sha256hash) {\n return sha256(abi.encodePacked(bytes32(uint256(input))));\n }\n}\n// ----\n// f(int256): 4 -> 0xe38990d0c7fc009880a9c07c23842e886c6bbdc964ce6bdd5817ad357335ee6f\n// f(int256): 5 -> 0x96de8fc8c256fa1e1556d41af431cace7dca68707c78dd88c3acab8b17164c47\n// f(int256): -1 -> 0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051\n" + }, + "sha256_packed.sol": { + "content": "contract C {\n function f(int256 _input) public returns (bytes32 hash) {\n uint24 b = 65536;\n uint c = 256;\n bytes32 input = bytes32(uint256(_input));\n return sha256(abi.encodePacked(uint8(8), input, b, input, c));\n }\n}\n// ----\n// f(int256): 4 -> 0x804e0d7003cfd70fc925dc103174d9f898ebb142ecc2a286da1abd22ac2ce3ac\n// f(int256): 5 -> 0xe94921945f9068726c529a290a954f412bcac53184bb41224208a31edbf63cf0\n// f(int256): -1 -> 0xf14def4d07cd185ddd8b10a81b2238326196a38867e6e6adbcc956dc913488c7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup.sol b/examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup.sol new file mode 100644 index 00000000..238f96b7 --- /dev/null +++ b/examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup.sol @@ -0,0 +1,40 @@ +contract C { + event ev(uint[], uint); + bytes public s; + function h() external returns (bytes memory) { + uint[] memory x = new uint[](2); + emit ev(x, 0x21); + bytes memory m = new bytes(63); + s = m; + s.push(); + return s; + } + function g() external returns (bytes memory) { + bytes memory m = new bytes(63); + assembly { + mstore8(add(m, add(32, 63)), 0x42) + } + s = m; + s.push(); + return s; + } + function f(bytes calldata c) external returns (bytes memory) { + s = c; + s.push(); + return s; + } +} +// ==== +// compileViaYul: also +// ---- +// constructor() -> +// gas irOptimized: 82100 +// gas irOptimized code: 357600 +// gas legacy: 101532 +// gas legacy code: 604800 +// gas legacyOptimized: 84956 +// gas legacyOptimized code: 391800 +// h() -> 0x20, 0x40, 0x00, 0 +// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00 +// g() -> 0x20, 0x40, 0, 0x00 +// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup_standard_input.json b/examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup_standard_input.json new file mode 100644 index 00000000..59dc38a3 --- /dev/null +++ b/examples/test/semanticTests/byte_array_to_storage_cleanup_1/byte_array_to_storage_cleanup_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation.sol b/examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation.sol new file mode 100644 index 00000000..6edf9db4 --- /dev/null +++ b/examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation.sol @@ -0,0 +1,41 @@ +contract test { + function f() pure public returns (uint) { + uint x = 7; + { + x = 3; // This should still assign to the outer variable + uint x; + x = 4; // This should assign to the new one + } + return x; + } + function g() pure public returns (uint x) { + x = 7; + { + x = 3; + uint x; + return x; // This returns the new variable, i.e. 0 + } + } + function h() pure public returns (uint x, uint a, uint b) { + x = 7; + { + x = 3; + a = x; // This should read from the outer + uint x = 4; + b = x; + } + } + function i() pure public returns (uint x, uint a) { + x = 7; + { + x = 3; + uint x = x; // This should read from the outer and assign to the inner + a = x; + } + } +} +// ---- +// f() -> 3 +// g() -> 0 +// h() -> 3, 3, 4 +// i() -> 3, 3 diff --git a/examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation_standard_input.json b/examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation_standard_input.json new file mode 100644 index 00000000..71d8087d --- /dev/null +++ b/examples/test/semanticTests/c99_scoping_activation_1/c99_scoping_activation_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + }, + "c99_scoping_activation.sol": { + "content": "contract test {\n function f() pure public returns (uint) {\n uint x = 7;\n {\n x = 3; // This should still assign to the outer variable\n uint x;\n x = 4; // This should assign to the new one\n }\n return x;\n }\n function g() pure public returns (uint x) {\n x = 7;\n {\n x = 3;\n uint x;\n return x; // This returns the new variable, i.e. 0\n }\n }\n function h() pure public returns (uint x, uint a, uint b) {\n x = 7;\n {\n x = 3;\n a = x; // This should read from the outer\n uint x = 4;\n b = x;\n }\n }\n function i() pure public returns (uint x, uint a) {\n x = 7;\n {\n x = 3;\n uint x = x; // This should read from the outer and assign to the inner\n a = x;\n }\n }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access.sol b/examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access.sol new file mode 100644 index 00000000..6dedc2a7 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; +contract C { + function f(uint256[] calldata x, uint256 i) external returns (uint256) { + return x[i]; + } + function f(uint256[][] calldata x, uint256 i, uint256 j) external returns (uint256) { + return x[i][j]; + } +} +// ---- +// f(uint256[],uint256): 0x40, 0, 0 -> FAILURE, hex"4e487b71", 0x32 +// f(uint256[],uint256): 0x40, 0, 1, 23 -> 23 +// f(uint256[],uint256): 0x40, 1, 1, 23 -> FAILURE, hex"4e487b71", 0x32 +// f(uint256[],uint256): 0x40, 0, 2, 23, 42 -> 23 +// f(uint256[],uint256): 0x40, 1, 2, 23, 42 -> 42 +// f(uint256[],uint256): 0x40, 2, 2, 23, 42 -> FAILURE, hex"4e487b71", 0x32 +// f(uint256[][],uint256,uint256): 0x60, 0, 0 -> FAILURE +// f(uint256[][],uint256,uint256): 0x60, 0, 0, 1, 0x20, 1, 23 -> 23 diff --git a/examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access_standard_input.json b/examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access_standard_input.json new file mode 100644 index 00000000..c8c35371 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_access/calldata_array_access_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + }, + "calldata_memory_mixed.sol": { + "content": "contract C {\n function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n public\n returns (uint, bytes1, bytes1, bytes1)\n {\n return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n }\n function g() public returns (uint, bytes1, bytes1, bytes1) {\n bytes memory x = new bytes(3);\n bytes memory y = new bytes(4);\n bytes memory z = new bytes(7);\n x[1] = 0x08;\n y[1] = 0x09;\n z[1] = 0x0a;\n return this.f(x, y, z);\n }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_bytes_internal.sol": { + "content": "contract C {\n function f(bytes calldata b, uint i) internal pure returns (bytes1) {\n return b[i];\n }\n function f(uint, bytes calldata b, uint) external pure returns (bytes1) {\n return f(b, 2);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 7, 4, \"abcd\" -> \"c\"\n" + }, + "calldata_attached_to_bytes.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(bytes calldata _b) internal pure returns (bytes1, bytes1) {\n return (_b[1], _b[0]);\n }\n}\n\ncontract C {\n using L for bytes;\n\n function test(uint, bytes calldata _b, uint) external pure returns (bytes1, bytes1) {\n return _b.reverse();\n }\n}\n// ----\n// test(uint256,bytes,uint256): 7, 0x60, 4, 2, \"ab\" -> \"b\", \"a\"\n" + }, + "calldata_internal_library.sol": { + "content": "library L {\n function f(uint, bytes calldata _x, uint) internal returns (bytes1) {\n return _x[2];\n }\n}\ncontract C {\n function f(bytes calldata a)\n external\n returns (bytes1)\n {\n return L.f(3, a, 9);\n }\n function g() public returns (bytes1) {\n bytes memory x = new bytes(4);\n x[2] = 0x08;\n return this.f(x);\n }\n}\n// ----\n// g() -> 0x0800000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_array_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 i) external returns (uint256) {\n return x[i];\n }\n function f(uint256[][] calldata x, uint256 i, uint256 j) external returns (uint256) {\n return x[i][j];\n }\n}\n// ----\n// f(uint256[],uint256): 0x40, 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[],uint256): 0x40, 0, 1, 23 -> 23\n// f(uint256[],uint256): 0x40, 1, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[],uint256): 0x40, 0, 2, 23, 42 -> 23\n// f(uint256[],uint256): 0x40, 1, 2, 23, 42 -> 42\n// f(uint256[],uint256): 0x40, 2, 2, 23, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][],uint256,uint256): 0x60, 0, 0 -> FAILURE\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 1, 0x20, 1, 23 -> 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes.sol b/examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes.sol new file mode 100644 index 00000000..932f1961 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes.sol @@ -0,0 +1,75 @@ +pragma abicoder v2; + + +contract C { + function f1(bytes[1] calldata a) + external + returns (uint256, uint256, uint256, uint256) + { + return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2])); + } + + function f2(bytes[1] calldata a, bytes[1] calldata b) + external + returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256) + { + return ( + a[0].length, + uint8(a[0][0]), + uint8(a[0][1]), + uint8(a[0][2]), + b[0].length, + uint8(b[0][0]), + uint8(b[0][1]) + ); + } + + function g1(bytes[2] calldata a) + external + returns ( + uint256, + uint256, + uint256, + uint256, + uint256, + uint256, + uint256, + uint256 + ) + { + return ( + a[0].length, + uint8(a[0][0]), + uint8(a[0][1]), + uint8(a[0][2]), + a[1].length, + uint8(a[1][0]), + uint8(a[1][1]), + uint8(a[1][2]) + ); + } + + function g2(bytes[] calldata a) external returns (uint256[8] memory) { + return [ + a.length, + a[0].length, + uint8(a[0][0]), + uint8(a[0][1]), + a[1].length, + uint8(a[1][0]), + uint8(a[1][1]), + uint8(a[1][2]) + ]; + } +} + +// via yul disabled because of stack issues. + +// ==== +// compileViaYul: false +// ---- +// f1(bytes[1]): 0x20, 0x20, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3 +// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000", 0x20, 0x2, hex"0102000000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2 +// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000", 0x3, hex"0405060000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6 +// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex"0102030000000000000000000000000000000000000000000000000000000000" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3 +// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex"0102000000000000000000000000000000000000000000000000000000000000", 0x3, hex"0405060000000000000000000000000000000000000000000000000000000000" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 diff --git a/examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes_standard_input.json b/examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes_standard_input.json new file mode 100644 index 00000000..ecd8678e --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_dynamic_bytes/calldata_array_dynamic_bytes_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access.sol b/examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access.sol new file mode 100644 index 00000000..634e3569 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access.sol @@ -0,0 +1,43 @@ +pragma abicoder v2; +contract C { + function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) { + return uint256[](x[s:e]).length; + } + function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) { + return uint256[](x[s:e][ss:ee]).length; + } + function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) { + return uint256[](x[s:]).length; + } + function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) { + return uint256[](x[:e]).length; + } + function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) { + return uint256[](x[s:e])[idx]; + } + function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) { + return x[s:e][idx]; + } + function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) { + return x[s:][idx]; + } + function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) { + return x[:e][idx]; + } +} +// ---- +// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2 +// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE +// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0 +// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE +// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3 +// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1 +// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE +// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3 +// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE +// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3 +// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4 +// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex"4e487b71", 0x32 +// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4 +// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access_standard_input.json b/examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access_standard_input.json new file mode 100644 index 00000000..085f9596 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_index_range_access/calldata_array_index_range_access_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length.sol b/examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length.sol new file mode 100644 index 00000000..779d261a --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length.sol @@ -0,0 +1,32 @@ +pragma abicoder v2; +contract C { + function f(uint256[] calldata x) external returns (uint256) { + return x.length; + } + function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) { + l1 = x.length; + if (l1 > 0) l2 = x[0].length; + if (l1 > 1) l3 = x[1].length; + } + function f(uint256[2] calldata x) external returns (uint256) { + return x.length; + } +} +// ---- +// f(uint256[]): 0x20, 0 -> 0 +// f(uint256[]): 0x20, 1, 23 -> 1 +// f(uint256[]): 0x20, 2, 23, 42 -> 2 +// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3 +// f(uint256[2]): 23, 42 -> 2 +// f(uint256[][]): 0x20, 0 -> 0, 0, 0 +// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0 +// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0 +// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0 +// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0 +// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0 +// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0 +// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2 +// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0 +// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2 +// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1 +// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2 diff --git a/examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length_standard_input.json b/examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length_standard_input.json new file mode 100644 index 00000000..90baad13 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_length/calldata_array_length_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional.sol b/examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional.sol new file mode 100644 index 00000000..42c360be --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + +contract C { + function f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) { + a = x.length; + b = x[i].length; + c = x[i][j].length; + d = x[i][j][k]; + } +} +// ---- +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42 +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23 +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23 +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17 +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex"4e487b71", 0x32 +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex"4e487b71", 0x32 +// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional_standard_input.json b/examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional_standard_input.json new file mode 100644 index 00000000..9e42ebe7 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_array_three_dimensional/calldata_array_three_dimensional_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes.sol b/examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes.sol new file mode 100644 index 00000000..1b6e7379 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; + +library L { + function reverse(bytes calldata _b) internal pure returns (bytes1, bytes1) { + return (_b[1], _b[0]); + } +} + +contract C { + using L for bytes; + + function test(uint, bytes calldata _b, uint) external pure returns (bytes1, bytes1) { + return _b.reverse(); + } +} +// ---- +// test(uint256,bytes,uint256): 7, 0x60, 4, 2, "ab" -> "b", "a" diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes_standard_input.json b/examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes_standard_input.json new file mode 100644 index 00000000..138e2443 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_bytes/calldata_attached_to_bytes_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + }, + "calldata_memory_mixed.sol": { + "content": "contract C {\n function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n public\n returns (uint, bytes1, bytes1, bytes1)\n {\n return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n }\n function g() public returns (uint, bytes1, bytes1, bytes1) {\n bytes memory x = new bytes(3);\n bytes memory y = new bytes(4);\n bytes memory z = new bytes(7);\n x[1] = 0x08;\n y[1] = 0x09;\n z[1] = 0x0a;\n return this.f(x, y, z);\n }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_bytes_internal.sol": { + "content": "contract C {\n function f(bytes calldata b, uint i) internal pure returns (bytes1) {\n return b[i];\n }\n function f(uint, bytes calldata b, uint) external pure returns (bytes1) {\n return f(b, 2);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 7, 4, \"abcd\" -> \"c\"\n" + }, + "calldata_attached_to_bytes.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(bytes calldata _b) internal pure returns (bytes1, bytes1) {\n return (_b[1], _b[0]);\n }\n}\n\ncontract C {\n using L for bytes;\n\n function test(uint, bytes calldata _b, uint) external pure returns (bytes1, bytes1) {\n return _b.reverse();\n }\n}\n// ----\n// test(uint256,bytes,uint256): 7, 0x60, 4, 2, \"ab\" -> \"b\", \"a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice.sol b/examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice.sol new file mode 100644 index 00000000..5803ef6e --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +library L { + function reverse(uint[] calldata _a) internal pure returns (uint, uint) { + return (_a[1], _a[0]); + } +} + +contract C { + using L for *; + + function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) { + return _a.reverse(); + } + + function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) { + return _a[:].reverse(); + } +} +// ---- +// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66 +// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66 diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice_standard_input.json b/examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice_standard_input.json new file mode 100644 index 00000000..abc32d5a --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_dynamic_array_or_slice/calldata_attached_to_dynamic_array_or_slice_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array.sol b/examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array.sol new file mode 100644 index 00000000..a5158dad --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; + +library L { + function reverse(uint[2] calldata _a) internal pure returns (uint, uint) { + return (_a[1], _a[0]); + } +} + +contract C { + using L for uint[2]; + + function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) { + return _a.reverse(); + } +} +// ---- +// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66 diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array_standard_input.json b/examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array_standard_input.json new file mode 100644 index 00000000..da7d72bf --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_static_array/calldata_attached_to_static_array_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct.sol b/examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct.sol new file mode 100644 index 00000000..ee442047 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +struct S { + uint x; + uint y; +} + +library L { + function reverse(S calldata _s) internal pure returns (uint, uint) { + return (_s.y, _s.x); + } +} + +contract C { + using L for S; + + function test(uint, S calldata _s, uint) external pure returns (uint, uint) { + return _s.reverse(); + } +} +// ---- +// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66 diff --git a/examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct_standard_input.json b/examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct_standard_input.json new file mode 100644 index 00000000..7afb36b8 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_attached_to_struct/calldata_attached_to_struct_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol b/examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol new file mode 100644 index 00000000..eb19897c --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds.sol @@ -0,0 +1,10 @@ +pragma abicoder v2; +contract C { + function f(bytes[] calldata a, uint256 i) external returns (uint) { + return uint8(a[0][i]); + } +} +// ---- +// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex"6162" -> 0x61 +// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex"6162" -> 0x62 +// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex"6162" -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json b/examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json new file mode 100644 index 00000000..2e5431a4 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_array_bounds/calldata_bytes_array_bounds_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external.sol b/examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external.sol new file mode 100644 index 00000000..a3975827 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external.sol @@ -0,0 +1,12 @@ +contract CalldataTest { + function test(bytes calldata x) public returns (bytes calldata) { + return x; + } + function tester(bytes calldata x) public returns (bytes1) { + return this.test(x)[2]; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// tester(bytes): 0x20, 0x08, "abcdefgh" -> "c" diff --git a/examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external_standard_input.json b/examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external_standard_input.json new file mode 100644 index 00000000..7f5cbf97 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_external/calldata_bytes_external_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal.sol b/examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal.sol new file mode 100644 index 00000000..79cf94be --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal.sol @@ -0,0 +1,10 @@ +contract C { + function f(bytes calldata b, uint i) internal pure returns (bytes1) { + return b[i]; + } + function f(uint, bytes calldata b, uint) external pure returns (bytes1) { + return f(b, 2); + } +} +// ---- +// f(uint256,bytes,uint256): 7, 0x60, 7, 4, "abcd" -> "c" diff --git a/examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal_standard_input.json b/examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal_standard_input.json new file mode 100644 index 00000000..96689bf5 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_internal/calldata_bytes_internal_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + }, + "calldata_memory_mixed.sol": { + "content": "contract C {\n function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n public\n returns (uint, bytes1, bytes1, bytes1)\n {\n return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n }\n function g() public returns (uint, bytes1, bytes1, bytes1) {\n bytes memory x = new bytes(3);\n bytes memory y = new bytes(4);\n bytes memory z = new bytes(7);\n x[1] = 0x08;\n y[1] = 0x09;\n z[1] = 0x0a;\n return this.f(x, y, z);\n }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_bytes_internal.sol": { + "content": "contract C {\n function f(bytes calldata b, uint i) internal pure returns (bytes1) {\n return b[i];\n }\n function f(uint, bytes calldata b, uint) external pure returns (bytes1) {\n return f(b, 2);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 7, 4, \"abcd\" -> \"c\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory.sol b/examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory.sol new file mode 100644 index 00000000..164ac8a8 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes calldata data) external returns (bytes32) { + return keccak256(bytes(data)); + } +} +// ---- +// f(bytes): 0x20, 0x08, "abcdefgh" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d diff --git a/examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory_standard_input.json b/examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory_standard_input.json new file mode 100644 index 00000000..1d40ff83 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_to_memory/calldata_bytes_to_memory_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode.sol b/examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode.sol new file mode 100644 index 00000000..5f30aff3 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes calldata data) external returns (bytes memory) { + return abi.encode(bytes(data)); + } +} +// ---- +// f(bytes): 0x20, 0x08, "abcdefgh" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744 diff --git a/examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode_standard_input.json b/examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode_standard_input.json new file mode 100644 index 00000000..4d15c499 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_bytes_to_memory_encode/calldata_bytes_to_memory_encode_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer.sol b/examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer.sol new file mode 100644 index 00000000..ee4bdf58 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer.sol @@ -0,0 +1,17 @@ +contract C { + function(bytes calldata) returns (bytes1) x; + constructor() { x = f; } + function f(bytes calldata b) internal pure returns (bytes1) { + return b[2]; + } + function h(bytes calldata b) external returns (bytes1) { + return x(b); + } + function g() external returns (bytes1) { + bytes memory a = new bytes(34); + a[2] = bytes1(uint8(7)); + return this.h(a); + } +} +// ---- +// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer_standard_input.json b/examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer_standard_input.json new file mode 100644 index 00000000..de0fe9e5 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_function_pointer/calldata_internal_function_pointer_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library.sol b/examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library.sol new file mode 100644 index 00000000..adc9963a --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library.sol @@ -0,0 +1,20 @@ +library L { + function f(uint, bytes calldata _x, uint) internal returns (bytes1) { + return _x[2]; + } +} +contract C { + function f(bytes calldata a) + external + returns (bytes1) + { + return L.f(3, a, 9); + } + function g() public returns (bytes1) { + bytes memory x = new bytes(4); + x[2] = 0x08; + return this.f(x); + } +} +// ---- +// g() -> 0x0800000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library_standard_input.json b/examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library_standard_input.json new file mode 100644 index 00000000..45a2a03a --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_library/calldata_internal_library_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + }, + "calldata_memory_mixed.sol": { + "content": "contract C {\n function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n public\n returns (uint, bytes1, bytes1, bytes1)\n {\n return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n }\n function g() public returns (uint, bytes1, bytes1, bytes1) {\n bytes memory x = new bytes(3);\n bytes memory y = new bytes(4);\n bytes memory z = new bytes(7);\n x[1] = 0x08;\n y[1] = 0x09;\n z[1] = 0x0a;\n return this.f(x, y, z);\n }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_bytes_internal.sol": { + "content": "contract C {\n function f(bytes calldata b, uint i) internal pure returns (bytes1) {\n return b[i];\n }\n function f(uint, bytes calldata b, uint) external pure returns (bytes1) {\n return f(b, 2);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 7, 4, \"abcd\" -> \"c\"\n" + }, + "calldata_attached_to_bytes.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(bytes calldata _b) internal pure returns (bytes1, bytes1) {\n return (_b[1], _b[0]);\n }\n}\n\ncontract C {\n using L for bytes;\n\n function test(uint, bytes calldata _b, uint) external pure returns (bytes1, bytes1) {\n return _b.reverse();\n }\n}\n// ----\n// test(uint256,bytes,uint256): 7, 0x60, 4, 2, \"ab\" -> \"b\", \"a\"\n" + }, + "calldata_internal_library.sol": { + "content": "library L {\n function f(uint, bytes calldata _x, uint) internal returns (bytes1) {\n return _x[2];\n }\n}\ncontract C {\n function f(bytes calldata a)\n external\n returns (bytes1)\n {\n return L.f(3, a, 9);\n }\n function g() public returns (bytes1) {\n bytes memory x = new bytes(4);\n x[2] = 0x08;\n return this.f(x);\n }\n}\n// ----\n// g() -> 0x0800000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array.sol b/examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array.sol new file mode 100644 index 00000000..26343b7e --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) { + return (s[0][1], s[1]); + } + function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) { + (uint x, uint[] calldata y) = g(s); + return (x, y[0]); + } + function g() public returns (uint, uint) { + uint[][2] memory x; + x[0] = new uint[](2); + x[1] = new uint[](2); + x[0][1] = 7; + x[1][0] = 8; + return this.f(4, x, 5); + } +} +// ---- +// g() -> 7, 8 diff --git a/examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array_standard_input.json b/examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array_standard_input.json new file mode 100644 index 00000000..7a017bda --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_multi_array/calldata_internal_multi_array_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array.sol b/examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array.sol new file mode 100644 index 00000000..cd5a8cfe --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array.sol @@ -0,0 +1,17 @@ +contract C { + function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) { + return (s[0][1], s[1]); + } + function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) { + (uint x, uint[3] calldata y) = g(s); + return (x, y[0]); + } + function g() public returns (uint, uint) { + uint[3][2] memory x; + x[0][1] = 7; + x[1][0] = 8; + return this.f(4, x, 5); + } +} +// ---- +// g() -> 7, 8 diff --git a/examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array_standard_input.json b/examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array_standard_input.json new file mode 100644 index 00000000..2df38994 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_internal_multi_fixed_array/calldata_internal_multi_fixed_array_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed.sol b/examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed.sol new file mode 100644 index 00000000..f5948d2d --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed.sol @@ -0,0 +1,19 @@ +contract C { + function f(bytes memory _a, bytes calldata _b, bytes memory _c) + public + returns (uint, bytes1, bytes1, bytes1) + { + return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]); + } + function g() public returns (uint, bytes1, bytes1, bytes1) { + bytes memory x = new bytes(3); + bytes memory y = new bytes(4); + bytes memory z = new bytes(7); + x[1] = 0x08; + y[1] = 0x09; + z[1] = 0x0a; + return this.f(x, y, z); + } +} +// ---- +// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed_standard_input.json b/examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed_standard_input.json new file mode 100644 index 00000000..addd5efb --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_memory_mixed/calldata_memory_mixed_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + }, + "calldata_memory_mixed.sol": { + "content": "contract C {\n function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n public\n returns (uint, bytes1, bytes1, bytes1)\n {\n return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n }\n function g() public returns (uint, bytes1, bytes1, bytes1) {\n bytes memory x = new bytes(3);\n bytes memory y = new bytes(4);\n bytes memory z = new bytes(7);\n x[1] = 0x08;\n y[1] = 0x09;\n z[1] = 0x0a;\n return this.f(x, y, z);\n }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array.sol b/examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array.sol new file mode 100644 index 00000000..79efb171 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + + +contract C { + function f(string[] calldata a) + external + returns (uint256, uint256, uint256, string memory) + { + string memory s1 = a[0]; + bytes memory m1 = bytes(s1); + return (a.length, m1.length, uint8(m1[0]), s1); + } +} +// ---- +// f(string[]): 0x20, 0x1, 0x20, 0x2, hex"6162000000000000000000000000000000000000000000000000000000000000" -> 1, 2, 97, 0x80, 2, "ab" diff --git a/examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array_standard_input.json b/examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array_standard_input.json new file mode 100644 index 00000000..aeeb044f --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_string_array/calldata_string_array_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_struct/calldata_struct.sol b/examples/test/semanticTests/calldata_calldata_struct/calldata_struct.sol new file mode 100644 index 00000000..247c00a7 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_struct/calldata_struct.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +struct S { + uint x; + uint y; +} + +library L { + function reverse(S calldata _s) internal pure returns (uint, uint) { + return (_s.y, _s.x); + } +} + +contract C { + function test(uint, S calldata _s, uint) external pure returns (uint, uint) { + return L.reverse(_s); + } +} +// ---- +// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66 diff --git a/examples/test/semanticTests/calldata_calldata_struct/calldata_struct_standard_input.json b/examples/test/semanticTests/calldata_calldata_struct/calldata_struct_standard_input.json new file mode 100644 index 00000000..b6dd0897 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_struct/calldata_struct_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning.sol b/examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning.sol new file mode 100644 index 00000000..45b323b3 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint8 a; + bytes1 b; + } + + function f(S calldata s) external pure returns (uint256 a, bytes32 b) { + uint8 tmp1 = s.a; + bytes1 tmp2 = s.b; + assembly { + a := tmp1 + b := tmp2 + } + } +} +// ---- +// f((uint8,bytes1)): 0x12, hex"3400000000000000000000000000000000000000000000000000000000000000" -> 0x12, hex"3400000000000000000000000000000000000000000000000000000000000000" # double check that the valid case goes through # +// f((uint8,bytes1)): 0x1234, hex"5678000000000000000000000000000000000000000000000000000000000000" -> FAILURE +// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE diff --git a/examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning_standard_input.json b/examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning_standard_input.json new file mode 100644 index 00000000..cc4bd600 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_struct_cleaning/calldata_struct_cleaning_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal.sol b/examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal.sol new file mode 100644 index 00000000..8a6c2687 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; + +struct S { + uint x; + uint y; +} + +contract C { + function f(S calldata s) internal pure returns (uint, uint) { + return (s.x, s.y); + } + function f(uint, S calldata s, uint) external pure returns (uint, uint) { + return f(s); + } +} +// ---- +// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2 diff --git a/examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal_standard_input.json b/examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal_standard_input.json new file mode 100644 index 00000000..10fbaa82 --- /dev/null +++ b/examples/test/semanticTests/calldata_calldata_struct_internal/calldata_struct_internal_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data.sol b/examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data.sol new file mode 100644 index 00000000..33ab1845 --- /dev/null +++ b/examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data.sol @@ -0,0 +1,17 @@ +contract c { + function set() public returns (bool) { data = msg.data; return true; } + function checkIfDataIsEmpty() public returns (bool) { return data.length == 0; } + function sendMessage() public returns (bool, bytes memory) { bytes memory emptyData; return address(this).call(emptyData);} + fallback() external { data = msg.data; } + bytes data; +} +// ==== +// EVMVersion: >=byzantium +// ---- +// (): 1, 2, 3, 4, 5 -> +// gas irOptimized: 155122 +// gas legacy: 155473 +// gas legacyOptimized: 155295 +// checkIfDataIsEmpty() -> false +// sendMessage() -> true, 0x40, 0 +// checkIfDataIsEmpty() -> true diff --git a/examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data_standard_input.json b/examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data_standard_input.json new file mode 100644 index 00000000..5d4a73a4 --- /dev/null +++ b/examples/test/semanticTests/calldata_copy_from_calldata_removes_bytes_data/copy_from_calldata_removes_bytes_data_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return L.reverse(_s);\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_array_index_range_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 s, uint256 e) external returns (uint256) {\n return uint256[](x[s:e]).length;\n }\n function f(uint256[] calldata x, uint256 s, uint256 e, uint256 ss, uint256 ee) external returns (uint256) {\n return uint256[](x[s:e][ss:ee]).length;\n }\n function f_s_only(uint256[] calldata x, uint256 s) external returns (uint256) {\n return uint256[](x[s:]).length;\n }\n function f_e_only(uint256[] calldata x, uint256 e) external returns (uint256) {\n return uint256[](x[:e]).length;\n }\n function g(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return uint256[](x[s:e])[idx];\n }\n function gg(uint256[] calldata x, uint256 s, uint256 e, uint256 idx) external returns (uint256) {\n return x[s:e][idx];\n }\n function gg_s_only(uint256[] calldata x, uint256 s, uint256 idx) external returns (uint256) {\n return x[s:][idx];\n }\n function gg_e_only(uint256[] calldata x, uint256 e, uint256 idx) external returns (uint256) {\n return x[:e][idx];\n }\n}\n// ----\n// f(uint256[],uint256,uint256): 0x60, 2, 4, 5, 1, 2, 3, 4, 5 -> 2\n// f(uint256[],uint256,uint256): 0x60, 2, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 3, 3, 5, 1, 2, 3, 4, 5 -> 0\n// f(uint256[],uint256,uint256): 0x60, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f(uint256[],uint256,uint256): 0x60, 0, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 2, 5, 1, 2, 3, 4, 5 -> 1\n// f(uint256[],uint256,uint256,uint256,uint256): 0xA0, 1, 3, 1, 4, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_s_only(uint256[],uint256): 0x40, 2, 5, 1, 2, 3, 4, 5 -> 3\n// f_s_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// f_e_only(uint256[],uint256): 0x40, 3, 5, 1, 2, 3, 4, 5 -> 3\n// f_e_only(uint256[],uint256): 0x40, 6, 5, 1, 2, 3, 4, 5 -> FAILURE\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// g(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 1, 5, 1, 2, 3, 4, 5 -> 4\n// gg(uint256[],uint256,uint256,uint256): 0x80, 2, 4, 3, 5, 1, 2, 3, 4, 5 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_array_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x) external returns (uint256) {\n return x.length;\n }\n function f(uint256[][] calldata x) external returns (uint256 l1, uint256 l2, uint256 l3) {\n l1 = x.length;\n if (l1 > 0) l2 = x[0].length;\n if (l1 > 1) l3 = x[1].length;\n }\n function f(uint256[2] calldata x) external returns (uint256) {\n return x.length;\n }\n}\n// ----\n// f(uint256[]): 0x20, 0 -> 0\n// f(uint256[]): 0x20, 1, 23 -> 1\n// f(uint256[]): 0x20, 2, 23, 42 -> 2\n// f(uint256[]): 0x20, 3, 23, 42, 17 -> 3\n// f(uint256[2]): 23, 42 -> 2\n// f(uint256[][]): 0x20, 0 -> 0, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 0 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x00 -> 1, 0, 0\n// f(uint256[][]): 0x20, 1, 0x20, 1, 23 -> 1, 1, 0\n// f(uint256[][]): 0x20, 1, 0x20, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, 0x40, 0, 2, 23, 42 -> 1, 2, 0\n// f(uint256[][]): 0x20, 1, -32 -> 1, 1, 0\n// f(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 2, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xa0, 2, 23, 42, 0 -> 2, 2, 0\n// f(uint256[][]): 0x20, 2, 0xA0, 0x40, 2, 23, 42, 0 -> 2, 0, 2\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 1, 17 -> 2, 2, 1\n// f(uint256[][]): 0x20, 2, 0x40, 0xA0, 2, 23, 42, 2, 17, 13 -> 2, 2, 2\n" + }, + "calldata_attached_to_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\nlibrary L {\n function reverse(S calldata _s) internal pure returns (uint, uint) {\n return (_s.y, _s.x);\n }\n}\n\ncontract C {\n using L for S;\n\n function test(uint, S calldata _s, uint) external pure returns (uint, uint) {\n return _s.reverse();\n }\n}\n// ----\n// test(uint256,(uint256,uint256),uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_to_memory_encode.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes memory) {\n return abi.encode(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x20, 0x60, 0x20, 8, 44048183304486788309563647967830685498285570828042699209880294173606615711744\n" + }, + "calldata_bytes_array_bounds.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(bytes[] calldata a, uint256 i) external returns (uint) {\n return uint8(a[0][i]);\n }\n}\n// ----\n// f(bytes[],uint256): 0x40, 0, 1, 0x20, 2, hex\"6162\" -> 0x61\n// f(bytes[],uint256): 0x40, 1, 1, 0x20, 2, hex\"6162\" -> 0x62\n// f(bytes[],uint256): 0x40, 2, 1, 0x20, 2, hex\"6162\" -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_bytes_to_memory.sol": { + "content": "contract C {\n function f(bytes calldata data) external returns (bytes32) {\n return keccak256(bytes(data));\n }\n}\n// ----\n// f(bytes): 0x20, 0x08, \"abcdefgh\" -> 0x48624fa43c68d5c552855a4e2919e74645f683f5384f72b5b051b71ea41d4f2d\n" + }, + "calldata_array_dynamic_bytes.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f1(bytes[1] calldata a)\n external\n returns (uint256, uint256, uint256, uint256)\n {\n return (a[0].length, uint8(a[0][0]), uint8(a[0][1]), uint8(a[0][2]));\n }\n\n function f2(bytes[1] calldata a, bytes[1] calldata b)\n external\n returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256)\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n b[0].length,\n uint8(b[0][0]),\n uint8(b[0][1])\n );\n }\n\n function g1(bytes[2] calldata a)\n external\n returns (\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256,\n uint256\n )\n {\n return (\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n uint8(a[0][2]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n );\n }\n\n function g2(bytes[] calldata a) external returns (uint256[8] memory) {\n return [\n a.length,\n a[0].length,\n uint8(a[0][0]),\n uint8(a[0][1]),\n a[1].length,\n uint8(a[1][0]),\n uint8(a[1][1]),\n uint8(a[1][2])\n ];\n }\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// f1(bytes[1]): 0x20, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3\n// f2(bytes[1],bytes[1]): 0x40, 0xa0, 0x20, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x20, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x2, 0x1, 0x2\n// g1(bytes[2]): 0x20, 0x40, 0x80, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x4, 0x5, 0x6\n// g1(bytes[2]): 0x20, 0x40, 0x40, 0x3, hex\"0102030000000000000000000000000000000000000000000000000000000000\" -> 0x3, 0x1, 0x2, 0x3, 0x3, 0x1, 0x2, 0x3\n// g2(bytes[]): 0x20, 0x2, 0x40, 0x80, 0x2, hex\"0102000000000000000000000000000000000000000000000000000000000000\", 0x3, hex\"0405060000000000000000000000000000000000000000000000000000000000\" -> 0x2, 0x2, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6\n" + }, + "calldata_array_three_dimensional.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tfunction f(uint256[][2][] calldata x, uint256 i, uint256 j, uint256 k) external returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n\t\ta = x.length;\n\t\tb = x[i].length;\n\t\tc = x[i][j].length;\n\t\td = x[i][j][k];\n }\n}\n// ----\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 42\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> 1, 2, 1, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 23\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 0x20, 0x40, 0x80, 1, 42, 2, 23, 17 -> 1, 2, 2, 17\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 1, 0, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][2][],uint256,uint256,uint256): 0x80, 0, 2, 0, 1, 0x20, 0x40, 0x80, 1, 42, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_struct_cleaning.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint8 a;\n bytes1 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, bytes32 b) {\n uint8 tmp1 = s.a;\n bytes1 tmp2 = s.b;\n assembly {\n a := tmp1\n b := tmp2\n }\n }\n}\n// ----\n// f((uint8,bytes1)): 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" -> 0x12, hex\"3400000000000000000000000000000000000000000000000000000000000000\" # double check that the valid case goes through #\n// f((uint8,bytes1)): 0x1234, hex\"5678000000000000000000000000000000000000000000000000000000000000\" -> FAILURE\n// f((uint8,bytes1)): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "calldata_internal_function_pointer.sol": { + "content": "contract C {\n function(bytes calldata) returns (bytes1) x;\n constructor() { x = f; }\n function f(bytes calldata b) internal pure returns (bytes1) {\n return b[2];\n }\n function h(bytes calldata b) external returns (bytes1) {\n return x(b);\n }\n function g() external returns (bytes1) {\n bytes memory a = new bytes(34);\n a[2] = bytes1(uint8(7));\n return this.h(a);\n }\n}\n// ----\n// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_internal_multi_fixed_array.sol": { + "content": "contract C {\n function g(uint[3][2] calldata s) internal pure returns (uint, uint[3] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[3][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[3] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[3][2] memory x;\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_dynamic_array_or_slice.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for *;\n\n function testArray(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n\n function testSlice(uint, uint[] calldata _a, uint) external pure returns (uint, uint) {\n return _a[:].reverse();\n }\n}\n// ----\n// testArray(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n// testSlice(uint256,uint256[],uint256): 7, 0x60, 4, 2, 66, 77 -> 77, 66\n" + }, + "calldata_string_array.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(string[] calldata a)\n external\n returns (uint256, uint256, uint256, string memory)\n {\n string memory s1 = a[0];\n bytes memory m1 = bytes(s1);\n return (a.length, m1.length, uint8(m1[0]), s1);\n }\n}\n// ----\n// f(string[]): 0x20, 0x1, 0x20, 0x2, hex\"6162000000000000000000000000000000000000000000000000000000000000\" -> 1, 2, 97, 0x80, 2, \"ab\"\n" + }, + "calldata_struct_internal.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint x;\n uint y;\n}\n\ncontract C {\n function f(S calldata s) internal pure returns (uint, uint) {\n return (s.x, s.y);\n }\n function f(uint, S calldata s, uint) external pure returns (uint, uint) {\n return f(s);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 7, 1, 2, 4 -> 1, 2\n" + }, + "calldata_internal_multi_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function g(uint[][2] calldata s) internal pure returns (uint, uint[] calldata) {\n return (s[0][1], s[1]);\n }\n function f(uint, uint[][2] calldata s, uint) external pure returns (uint, uint) {\n (uint x, uint[] calldata y) = g(s);\n return (x, y[0]);\n }\n function g() public returns (uint, uint) {\n uint[][2] memory x;\n x[0] = new uint[](2);\n x[1] = new uint[](2);\n x[0][1] = 7;\n x[1][0] = 8;\n return this.f(4, x, 5);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "calldata_attached_to_static_array.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(uint[2] calldata _a) internal pure returns (uint, uint) {\n return (_a[1], _a[0]);\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function test(uint, uint[2] calldata _a, uint) external pure returns (uint, uint) {\n return _a.reverse();\n }\n}\n// ----\n// test(uint256,uint256[2],uint256): 7, 66, 77, 4 -> 77, 66\n" + }, + "calldata_bytes_external.sol": { + "content": "contract CalldataTest {\n function test(bytes calldata x) public returns (bytes calldata) {\n return x;\n }\n function tester(bytes calldata x) public returns (bytes1) {\n return this.test(x)[2];\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// tester(bytes): 0x20, 0x08, \"abcdefgh\" -> \"c\"\n" + }, + "calldata_memory_mixed.sol": { + "content": "contract C {\n function f(bytes memory _a, bytes calldata _b, bytes memory _c)\n public\n returns (uint, bytes1, bytes1, bytes1)\n {\n return (_a.length + _b.length + _c.length, _a[1], _b[1], _c[1]);\n }\n function g() public returns (uint, bytes1, bytes1, bytes1) {\n bytes memory x = new bytes(3);\n bytes memory y = new bytes(4);\n bytes memory z = new bytes(7);\n x[1] = 0x08;\n y[1] = 0x09;\n z[1] = 0x0a;\n return this.f(x, y, z);\n }\n}\n// ----\n// g() -> 0x0e, 0x0800000000000000000000000000000000000000000000000000000000000000, 0x0900000000000000000000000000000000000000000000000000000000000000, 0x0a00000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_bytes_internal.sol": { + "content": "contract C {\n function f(bytes calldata b, uint i) internal pure returns (bytes1) {\n return b[i];\n }\n function f(uint, bytes calldata b, uint) external pure returns (bytes1) {\n return f(b, 2);\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 7, 4, \"abcd\" -> \"c\"\n" + }, + "calldata_attached_to_bytes.sol": { + "content": "pragma abicoder v2;\n\nlibrary L {\n function reverse(bytes calldata _b) internal pure returns (bytes1, bytes1) {\n return (_b[1], _b[0]);\n }\n}\n\ncontract C {\n using L for bytes;\n\n function test(uint, bytes calldata _b, uint) external pure returns (bytes1, bytes1) {\n return _b.reverse();\n }\n}\n// ----\n// test(uint256,bytes,uint256): 7, 0x60, 4, 2, \"ab\" -> \"b\", \"a\"\n" + }, + "calldata_internal_library.sol": { + "content": "library L {\n function f(uint, bytes calldata _x, uint) internal returns (bytes1) {\n return _x[2];\n }\n}\ncontract C {\n function f(bytes calldata a)\n external\n returns (bytes1)\n {\n return L.f(3, a, 9);\n }\n function g() public returns (bytes1) {\n bytes memory x = new bytes(4);\n x[2] = 0x08;\n return this.f(x);\n }\n}\n// ----\n// g() -> 0x0800000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata_array_access.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[] calldata x, uint256 i) external returns (uint256) {\n return x[i];\n }\n function f(uint256[][] calldata x, uint256 i, uint256 j) external returns (uint256) {\n return x[i][j];\n }\n}\n// ----\n// f(uint256[],uint256): 0x40, 0, 0 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[],uint256): 0x40, 0, 1, 23 -> 23\n// f(uint256[],uint256): 0x40, 1, 1, 23 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[],uint256): 0x40, 0, 2, 23, 42 -> 23\n// f(uint256[],uint256): 0x40, 1, 2, 23, 42 -> 42\n// f(uint256[],uint256): 0x40, 2, 2, 23, 42 -> FAILURE, hex\"4e487b71\", 0x32\n// f(uint256[][],uint256,uint256): 0x60, 0, 0 -> FAILURE\n// f(uint256[][],uint256,uint256): 0x60, 0, 0, 1, 0x20, 1, 23 -> 23\n" + }, + "copy_from_calldata_removes_bytes_data.sol": { + "content": "contract c {\n function set() public returns (bool) { data = msg.data; return true; }\n function checkIfDataIsEmpty() public returns (bool) { return data.length == 0; }\n function sendMessage() public returns (bool, bytes memory) { bytes memory emptyData; return address(this).call(emptyData);}\n fallback() external { data = msg.data; }\n bytes data;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// (): 1, 2, 3, 4, 5 ->\n// gas irOptimized: 155122\n// gas legacy: 155473\n// gas legacyOptimized: 155295\n// checkIfDataIsEmpty() -> false\n// sendMessage() -> true, 0x40, 0\n// checkIfDataIsEmpty() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1.sol b/examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1.sol new file mode 100644 index 00000000..18fa6ed6 --- /dev/null +++ b/examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1.sol @@ -0,0 +1,25 @@ +pragma abicoder v1; +contract C { + function f(bool _b) public returns (uint256) { + if (_b) return 1; + else return 0; + } + + function g(bool _in) public returns (bool _out) { + _out = _in; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(bool): 0x0 -> 0x0 +// f(bool): 0x1 -> 0x1 +// f(bool): 0x2 -> 0x1 +// f(bool): 0x3 -> 0x1 +// f(bool): 0xff -> 0x1 +// g(bool): 0x0 -> 0x0 +// g(bool): 0x1 -> 0x1 +// g(bool): 0x2 -> 0x1 +// g(bool): 0x3 -> 0x1 +// g(bool): 0xff -> 0x1 diff --git a/examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1_standard_input.json b/examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1_standard_input.json new file mode 100644 index 00000000..ef9886ae --- /dev/null +++ b/examples/test/semanticTests/cleanup_bool_conversion_v1/bool_conversion_v1_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2.sol b/examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2.sol new file mode 100644 index 00000000..003cdb0e --- /dev/null +++ b/examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + + +contract C { + function f(bool _b) public returns (uint256) { + if (_b) return 1; + else return 0; + } + + function g(bool _in) public returns (bool _out) { + _out = _in; + } +} +// ---- +// f(bool): 0x0 -> 0x0 +// f(bool): 0x1 -> 0x1 +// f(bool): 0x2 -> FAILURE +// f(bool): 0x3 -> FAILURE +// f(bool): 0xff -> FAILURE +// g(bool): 0x0 -> 0x0 +// g(bool): 0x1 -> 0x1 +// g(bool): 0x2 -> FAILURE +// g(bool): 0x3 -> FAILURE +// g(bool): 0xff -> FAILURE diff --git a/examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2_standard_input.json b/examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2_standard_input.json new file mode 100644 index 00000000..eb567c84 --- /dev/null +++ b/examples/test/semanticTests/cleanup_bool_conversion_v2/bool_conversion_v2_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening.sol b/examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening.sol new file mode 100644 index 00000000..8718cb2e --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening.sol @@ -0,0 +1,30 @@ +contract C { + function f() public pure returns (address r) { + bytes21 x = 0x1122334455667788990011223344556677889900ff; + bytes20 y; + assembly { + y := x + } + address z = address(y); + assembly { + r := z + } + require(z == 0x1122334455667788990011223344556677889900); + } + + function g() public pure returns (address payable r) { + bytes21 x = 0x1122334455667788990011223344556677889900ff; + bytes20 y; + assembly { + y := x + } + address payable z = payable(address(y)); + assembly { + r := z + } + require(z == 0x1122334455667788990011223344556677889900); + } +} +// ---- +// f() -> 0x1122334455667788990011223344556677889900 +// g() -> 0x1122334455667788990011223344556677889900 diff --git a/examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening_standard_input.json new file mode 100644 index 00000000..6d933388 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_address_types_shortening/cleanup_address_types_shortening_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + }, + "exp_cleanup_smaller_base.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n // tests that ``e`` is not converted to uint8\n // right before the exp\n uint16 e = 0x100;\n uint8 b = 0x2;\n unchecked {\n return b**e;\n }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "exp_cleanup_nonzero_base.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n\t\t\tuint16 x = 0x166;\n return uint8(x)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_bytes_types_shortening_newCodeGen.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 r) {\n bytes4 x = 0xffffffff;\n bytes2 y = bytes2(x);\n assembly {\n r := y\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000\n" + }, + "indexed_log_topic_during_explicit_downcast.sol": { + "content": "contract C {\n function f() public pure returns (uint32 y) {\n uint8 x = uint8(uint256(0x31313131313131313131313131313131));\n assembly { y := x }\n }\n\n function g() public pure returns (bytes32 y) {\n bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131));\n assembly { y := x }\n }\n\n function h() external returns (bytes32 y) {\n bytes1 x;\n assembly { x := sub(0,1) }\n y = x;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x31\n// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000\n// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "cleanup_bytes_types_shortening_OldCodeGen.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 r) {\n bytes4 x = 0xffffffff;\n bytes2 y = bytes2(x);\n assembly {\n r := y\n }\n // At this point, r and y both store four bytes, but\n // y is properly cleaned before the equality check\n require(y == bytes2(0xffff));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000\n" + }, + "cleanup_address_types_shortening.sol": { + "content": "contract C {\n function f() public pure returns (address r) {\n bytes21 x = 0x1122334455667788990011223344556677889900ff;\n bytes20 y;\n assembly {\n y := x\n }\n address z = address(y);\n assembly {\n r := z\n }\n require(z == 0x1122334455667788990011223344556677889900);\n }\n\n function g() public pure returns (address payable r) {\n bytes21 x = 0x1122334455667788990011223344556677889900ff;\n bytes20 y;\n assembly {\n y := x\n }\n address payable z = payable(address(y));\n assembly {\n r := z\n }\n require(z == 0x1122334455667788990011223344556677889900);\n }\n}\n// ----\n// f() -> 0x1122334455667788990011223344556677889900\n// g() -> 0x1122334455667788990011223344556677889900\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1.sol b/examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1.sol new file mode 100644 index 00000000..a8622cb0 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1.sol @@ -0,0 +1,19 @@ +pragma abicoder v1; +// Checks that address types are properly cleaned before they are compared. +contract C { + function f(address a) public returns (uint256) { + if (a != 0x1234567890123456789012345678901234567890) return 1; + return 0; + } + + function g(address payable a) public returns (uint256) { + if (a != 0x1234567890123456789012345678901234567890) return 1; + return 0; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.# +// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 diff --git a/examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1_standard_input.json new file mode 100644 index 00000000..f635807c --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_address_types_v1/cleanup_address_types_v1_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2.sol b/examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2.sol new file mode 100644 index 00000000..73db35c3 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; + + +// Checks that address types are properly cleaned before they are compared. +contract C { + function f(address a) public returns (uint256) { + if (a != 0x1234567890123456789012345678901234567890) return 1; + return 0; + } + + function g(address payable a) public returns (uint256) { + if (a != 0x1234567890123456789012345678901234567890) return 1; + return 0; + } +} +// ---- +// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.# +// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE diff --git a/examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2_standard_input.json new file mode 100644 index 00000000..78e2f3e4 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_address_types_v2/cleanup_address_types_v2_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen.sol b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen.sol new file mode 100644 index 00000000..9ca68e6d --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen.sol @@ -0,0 +1,16 @@ +contract C { + function f() public pure returns (bytes32 r) { + bytes4 x = 0xffffffff; + bytes2 y = bytes2(x); + assembly { + r := y + } + // At this point, r and y both store four bytes, but + // y is properly cleaned before the equality check + require(y == bytes2(0xffff)); + } +} +// ==== +// compileViaYul: false +// ---- +// f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen_standard_input.json new file mode 100644 index 00000000..eecbc8bd --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_OldCodeGen/cleanup_bytes_types_shortening_OldCodeGen_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + }, + "exp_cleanup_smaller_base.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n // tests that ``e`` is not converted to uint8\n // right before the exp\n uint16 e = 0x100;\n uint8 b = 0x2;\n unchecked {\n return b**e;\n }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "exp_cleanup_nonzero_base.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n\t\t\tuint16 x = 0x166;\n return uint8(x)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_bytes_types_shortening_newCodeGen.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 r) {\n bytes4 x = 0xffffffff;\n bytes2 y = bytes2(x);\n assembly {\n r := y\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000\n" + }, + "indexed_log_topic_during_explicit_downcast.sol": { + "content": "contract C {\n function f() public pure returns (uint32 y) {\n uint8 x = uint8(uint256(0x31313131313131313131313131313131));\n assembly { y := x }\n }\n\n function g() public pure returns (bytes32 y) {\n bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131));\n assembly { y := x }\n }\n\n function h() external returns (bytes32 y) {\n bytes1 x;\n assembly { x := sub(0,1) }\n y = x;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x31\n// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000\n// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "cleanup_bytes_types_shortening_OldCodeGen.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 r) {\n bytes4 x = 0xffffffff;\n bytes2 y = bytes2(x);\n assembly {\n r := y\n }\n // At this point, r and y both store four bytes, but\n // y is properly cleaned before the equality check\n require(y == bytes2(0xffff));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen.sol b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen.sol new file mode 100644 index 00000000..b26ba564 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen.sol @@ -0,0 +1,13 @@ +contract C { + function f() public pure returns (bytes32 r) { + bytes4 x = 0xffffffff; + bytes2 y = bytes2(x); + assembly { + r := y + } + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen_standard_input.json new file mode 100644 index 00000000..ed623068 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_shortening_newCodeGen/cleanup_bytes_types_shortening_newCodeGen_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + }, + "exp_cleanup_smaller_base.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n // tests that ``e`` is not converted to uint8\n // right before the exp\n uint16 e = 0x100;\n uint8 b = 0x2;\n unchecked {\n return b**e;\n }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "exp_cleanup_nonzero_base.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n\t\t\tuint16 x = 0x166;\n return uint8(x)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_bytes_types_shortening_newCodeGen.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 r) {\n bytes4 x = 0xffffffff;\n bytes2 y = bytes2(x);\n assembly {\n r := y\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1.sol b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1.sol new file mode 100644 index 00000000..097da51e --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +// Checks that bytesXX types are properly cleaned before they are compared. +contract C { + function f(bytes2 a, uint16 x) public returns (uint256) { + if (a != "ab") return 1; + if (x != 0x0102) return 2; + if (bytes3(uint24(x)) != 0x000102) return 3; + return 0; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(bytes2,uint16): "abc", 0x40102 -> 0x0 # We input longer data on purpose. # diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1_standard_input.json new file mode 100644 index 00000000..1cbadfba --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v1/cleanup_bytes_types_v1_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2.sol b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2.sol new file mode 100644 index 00000000..8a95f10c --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + + +// Checks that bytesXX types are properly cleaned before they are compared. +contract C { + function f(bytes2 a, uint16 x) public returns (uint256) { + if (a != "ab") return 1; + if (x != 0x0102) return 2; + if (bytes3(uint24(x)) != 0x000102) return 3; + return 0; + } +} +// ---- +// f(bytes2,uint16): "abc", 0x40102 -> FAILURE # We input longer data on purpose. # diff --git a/examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2_standard_input.json new file mode 100644 index 00000000..7f1ed6ed --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_bytes_types_v2/cleanup_bytes_types_v2_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign.sol b/examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign.sol new file mode 100644 index 00000000..e0e62971 --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign.sol @@ -0,0 +1,12 @@ +contract C { + function test() public returns (uint256, uint256) { + uint32 a = 0xffffffff; + uint16 x = uint16(a); + uint16 y = x; + x /= 0x100; + y = y / 0x100; + return (x, y); + } +} +// ---- +// test() -> 0xff, 0xff diff --git a/examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign_standard_input.json b/examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign_standard_input.json new file mode 100644 index 00000000..44dd165a --- /dev/null +++ b/examples/test/semanticTests/cleanup_cleanup_in_compound_assign/cleanup_in_compound_assign_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup.sol b/examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup.sol new file mode 100644 index 00000000..746f21ef --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup.sol @@ -0,0 +1,10 @@ +contract C { + function f() public pure returns (uint x) { + unchecked { + uint8 y = uint8(2)**uint8(8); + return 0**y; + } + } +} +// ---- +// f() -> 0x1 diff --git a/examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup_standard_input.json b/examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup_standard_input.json new file mode 100644 index 00000000..dec65b78 --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup/exp_cleanup_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct.sol b/examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct.sol new file mode 100644 index 00000000..62f927b5 --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (uint8 x) { + unchecked { + return uint8(0)**uint8(uint8(2)**uint8(8)); + } + } +} +// ---- +// f() -> 0x1 diff --git a/examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct_standard_input.json b/examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct_standard_input.json new file mode 100644 index 00000000..a91e8d5e --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup_direct/exp_cleanup_direct_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base.sol b/examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base.sol new file mode 100644 index 00000000..de55afa9 --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base.sol @@ -0,0 +1,10 @@ +contract C { + function f() public pure returns (uint8 x) { + unchecked { + uint16 x = 0x166; + return uint8(x)**uint8(uint8(2)**uint8(8)); + } + } +} +// ---- +// f() -> 0x1 diff --git a/examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base_standard_input.json b/examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base_standard_input.json new file mode 100644 index 00000000..6142521a --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup_nonzero_base/exp_cleanup_nonzero_base_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + }, + "exp_cleanup_smaller_base.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n // tests that ``e`` is not converted to uint8\n // right before the exp\n uint16 e = 0x100;\n uint8 b = 0x2;\n unchecked {\n return b**e;\n }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "exp_cleanup_nonzero_base.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n\t\t\tuint16 x = 0x166;\n return uint8(x)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base.sol b/examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base.sol new file mode 100644 index 00000000..7b81d0a1 --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base.sol @@ -0,0 +1,13 @@ +contract C { + function f() public pure returns (uint16 x) { + // tests that ``e`` is not converted to uint8 + // right before the exp + uint16 e = 0x100; + uint8 b = 0x2; + unchecked { + return b**e; + } + } +} +// ---- +// f() -> 0x00 diff --git a/examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base_standard_input.json b/examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base_standard_input.json new file mode 100644 index 00000000..444b21a2 --- /dev/null +++ b/examples/test/semanticTests/cleanup_exp_cleanup_smaller_base/exp_cleanup_smaller_base_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + }, + "exp_cleanup_smaller_base.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n // tests that ``e`` is not converted to uint8\n // right before the exp\n uint16 e = 0x100;\n uint8 b = 0x2;\n unchecked {\n return b**e;\n }\n }\n}\n// ----\n// f() -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast.sol b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast.sol new file mode 100644 index 00000000..f0aa239b --- /dev/null +++ b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast.sol @@ -0,0 +1,23 @@ +contract C { + function f() public pure returns (uint32 y) { + uint8 x = uint8(uint256(0x31313131313131313131313131313131)); + assembly { y := x } + } + + function g() public pure returns (bytes32 y) { + bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131)); + assembly { y := x } + } + + function h() external returns (bytes32 y) { + bytes1 x; + assembly { x := sub(0,1) } + y = x; + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0x31 +// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000 +// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast_standard_input.json b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast_standard_input.json new file mode 100644 index 00000000..64c5283a --- /dev/null +++ b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast/indexed_log_topic_during_explicit_downcast_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + }, + "cleanup_address_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> FAILURE\n" + }, + "exp_cleanup_smaller_base.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n // tests that ``e`` is not converted to uint8\n // right before the exp\n uint16 e = 0x100;\n uint8 b = 0x2;\n unchecked {\n return b**e;\n }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "exp_cleanup_nonzero_base.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n\t\t\tuint16 x = 0x166;\n return uint8(x)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_bytes_types_shortening_newCodeGen.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 r) {\n bytes4 x = 0xffffffff;\n bytes2 y = bytes2(x);\n assembly {\n r := y\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000\n" + }, + "indexed_log_topic_during_explicit_downcast.sol": { + "content": "contract C {\n function f() public pure returns (uint32 y) {\n uint8 x = uint8(uint256(0x31313131313131313131313131313131));\n assembly { y := x }\n }\n\n function g() public pure returns (bytes32 y) {\n bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131));\n assembly { y := x }\n }\n\n function h() external returns (bytes32 y) {\n bytes1 x;\n assembly { x := sub(0,1) }\n y = x;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0x31\n// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000\n// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions.sol b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions.sol new file mode 100644 index 00000000..742c0269 --- /dev/null +++ b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions.sol @@ -0,0 +1,17 @@ +contract C { + event ev0(bytes1 indexed); + constructor() { + emit ev0(bytes1(bytes16(0x31313131313131313131313131313131))); + } + function j() external { + bytes1 x; + assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 } + emit ev0(x); + } +} +// ---- +// constructor() -> +// ~ emit ev0(bytes1): #"1" +// gas legacy: 168735 +// j() -> +// ~ emit ev0(bytes1): #"1" diff --git a/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions_standard_input.json b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions_standard_input.json new file mode 100644 index 00000000..0d4f5a89 --- /dev/null +++ b/examples/test/semanticTests/cleanup_indexed_log_topic_during_explicit_downcast_during_emissions/indexed_log_topic_during_explicit_downcast_during_emissions_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "cleanup_bytes_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> 0x0 # We input longer data on purpose. #\n" + }, + "cleanup_bytes_types_v2.sol": { + "content": "pragma abicoder v2;\n\n\n// Checks that bytesXX types are properly cleaned before they are compared.\ncontract C {\n function f(bytes2 a, uint16 x) public returns (uint256) {\n if (a != \"ab\") return 1;\n if (x != 0x0102) return 2;\n if (bytes3(uint24(x)) != 0x000102) return 3;\n return 0;\n }\n}\n// ----\n// f(bytes2,uint16): \"abc\", 0x40102 -> FAILURE # We input longer data on purpose. #\n" + }, + "bool_conversion_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> FAILURE\n// f(bool): 0x3 -> FAILURE\n// f(bool): 0xff -> FAILURE\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> FAILURE\n// g(bool): 0x3 -> FAILURE\n// g(bool): 0xff -> FAILURE\n" + }, + "bool_conversion_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(bool _b) public returns (uint256) {\n if (_b) return 1;\n else return 0;\n }\n\n function g(bool _in) public returns (bool _out) {\n _out = _in;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(bool): 0x0 -> 0x0\n// f(bool): 0x1 -> 0x1\n// f(bool): 0x2 -> 0x1\n// f(bool): 0x3 -> 0x1\n// f(bool): 0xff -> 0x1\n// g(bool): 0x0 -> 0x0\n// g(bool): 0x1 -> 0x1\n// g(bool): 0x2 -> 0x1\n// g(bool): 0x3 -> 0x1\n// g(bool): 0xff -> 0x1\n" + }, + "exp_cleanup.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n unchecked {\n uint8 y = uint8(2)**uint8(8);\n return 0**y;\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "cleanup_in_compound_assign.sol": { + "content": "contract C {\n function test() public returns (uint256, uint256) {\n uint32 a = 0xffffffff;\n uint16 x = uint16(a);\n uint16 y = x;\n x /= 0x100;\n y = y / 0x100;\n return (x, y);\n }\n}\n// ----\n// test() -> 0xff, 0xff\n" + }, + "cleanup_address_types_v1.sol": { + "content": "pragma abicoder v1;\n// Checks that address types are properly cleaned before they are compared.\ncontract C {\n function f(address a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n\n function g(address payable a) public returns (uint256) {\n if (a != 0x1234567890123456789012345678901234567890) return 1;\n return 0;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(address): 0xffff1234567890123456789012345678901234567890 -> 0x0 # We input longer data on purpose.#\n// g(address): 0xffff1234567890123456789012345678901234567890 -> 0x0\n" + }, + "exp_cleanup_direct.sol": { + "content": "contract C {\n function f() public pure returns (uint8 x) {\n unchecked {\n return uint8(0)**uint8(uint8(2)**uint8(8));\n }\n }\n}\n// ----\n// f() -> 0x1\n" + }, + "indexed_log_topic_during_explicit_downcast_during_emissions.sol": { + "content": "contract C {\n event ev0(bytes1 indexed);\n constructor() {\n emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));\n }\n function j() external {\n bytes1 x;\n assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }\n emit ev0(x);\n }\n}\n// ----\n// constructor() ->\n// ~ emit ev0(bytes1): #\"1\"\n// gas legacy: 168735\n// j() ->\n// ~ emit ev0(bytes1): #\"1\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod.sol b/examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod.sol new file mode 100644 index 00000000..4426f0c0 --- /dev/null +++ b/examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (int, int) { + int x = int((-(-5.2 % 3)) * 5); + int t = 5; + return (x, (-(-t % 3)) * 5); + } +} +// ---- +// f() -> 11, 10 diff --git a/examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod_standard_input.json b/examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod_standard_input.json new file mode 100644 index 00000000..47e047d5 --- /dev/null +++ b/examples/test/semanticTests/constantEvaluator_negative_fractional_mod/negative_fractional_mod_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "rounding.sol": { + "content": "contract C {\n int constant a = 7;\n int constant b = 3;\n int constant c = a / b;\n int constant d = (-a) / b;\n function f() public pure returns (uint, int, uint, int) {\n uint[c] memory x;\n uint[-d] memory y;\n return (x.length, c, y.length, -d);\n }\n}\n// ----\n// f() -> 2, 2, 2, 2\n" + }, + "negative_fractional_mod.sol": { + "content": "contract C {\n function f() public pure returns (int, int) {\n int x = int((-(-5.2 % 3)) * 5);\n int t = 5;\n return (x, (-(-t % 3)) * 5);\n }\n}\n// ----\n// f() -> 11, 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constantEvaluator_rounding/rounding.sol b/examples/test/semanticTests/constantEvaluator_rounding/rounding.sol new file mode 100644 index 00000000..837e87dc --- /dev/null +++ b/examples/test/semanticTests/constantEvaluator_rounding/rounding.sol @@ -0,0 +1,13 @@ +contract C { + int constant a = 7; + int constant b = 3; + int constant c = a / b; + int constant d = (-a) / b; + function f() public pure returns (uint, int, uint, int) { + uint[c] memory x; + uint[-d] memory y; + return (x.length, c, y.length, -d); + } +} +// ---- +// f() -> 2, 2, 2, 2 diff --git a/examples/test/semanticTests/constantEvaluator_rounding/rounding_standard_input.json b/examples/test/semanticTests/constantEvaluator_rounding/rounding_standard_input.json new file mode 100644 index 00000000..c0e0135e --- /dev/null +++ b/examples/test/semanticTests/constantEvaluator_rounding/rounding_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "rounding.sol": { + "content": "contract C {\n int constant a = 7;\n int constant b = 3;\n int constant c = a / b;\n int constant d = (-a) / b;\n function f() public pure returns (uint, int, uint, int) {\n uint[c] memory x;\n uint[-d] memory y;\n return (x.length, c, y.length, -d);\n }\n}\n// ----\n// f() -> 2, 2, 2, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression.sol b/examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression.sol new file mode 100644 index 00000000..ae405d8f --- /dev/null +++ b/examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression.sol @@ -0,0 +1,11 @@ +// Test for regression of https://github.com/ethereum/solidity/issues/8406 + +contract C { + address constant e = 0x1212121212121212121212121000002134593163; + + function f() public returns (bytes1 z) { + assembly { z := e } + } +} +// ---- +// f() -> 0x00 diff --git a/examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression_standard_input.json b/examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression_standard_input.json new file mode 100644 index 00000000..2c497c30 --- /dev/null +++ b/examples/test/semanticTests/constants_asm_address_constant_regression/asm_address_constant_regression_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level.sol b/examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level.sol new file mode 100644 index 00000000..4f907646 --- /dev/null +++ b/examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level.sol @@ -0,0 +1,9 @@ +address constant e = 0x1212121212121212121212121000002134593163; + +contract C { + function f() public returns (address z) { + assembly { z := e } + } +} +// ---- +// f() -> 0x1212121212121212121212121000002134593163 diff --git a/examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level_standard_input.json b/examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level_standard_input.json new file mode 100644 index 00000000..aa996b48 --- /dev/null +++ b/examples/test/semanticTests/constants_asm_constant_file_level/asm_constant_file_level_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_constant_string/constant_string.sol b/examples/test/semanticTests/constants_constant_string/constant_string.sol new file mode 100644 index 00000000..3b53102b --- /dev/null +++ b/examples/test/semanticTests/constants_constant_string/constant_string.sol @@ -0,0 +1,21 @@ +contract C { + bytes constant a = "\x03\x01\x02"; + bytes constant b = hex"030102"; + string constant c = "hello"; + + function f() public returns (bytes memory) { + return a; + } + + function g() public returns (bytes memory) { + return b; + } + + function h() public returns (bytes memory) { + return bytes(c); + } +} +// ---- +// f() -> 0x20, 3, "\x03\x01\x02" +// g() -> 0x20, 3, "\x03\x01\x02" +// h() -> 0x20, 5, "hello" diff --git a/examples/test/semanticTests/constants_constant_string/constant_string_standard_input.json b/examples/test/semanticTests/constants_constant_string/constant_string_standard_input.json new file mode 100644 index 00000000..d34cb1e7 --- /dev/null +++ b/examples/test/semanticTests/constants_constant_string/constant_string_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + }, + "constant_string.sol": { + "content": "contract C {\n bytes constant a = \"\\x03\\x01\\x02\";\n bytes constant b = hex\"030102\";\n string constant c = \"hello\";\n\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level.sol b/examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level.sol new file mode 100644 index 00000000..0ff332c4 --- /dev/null +++ b/examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level.sol @@ -0,0 +1,30 @@ +bytes constant a = "\x03\x01\x02"; +bytes constant b = hex"030102"; +string constant c = "hello"; +uint256 constant x = 56; +enum ActionChoices {GoLeft, GoRight, GoStraight, Sit} +ActionChoices constant choices = ActionChoices.GoRight; +bytes32 constant st = "abc\x00\xff__"; + +contract C { + function f() public returns (bytes memory) { + return a; + } + + function g() public returns (bytes memory) { + return b; + } + + function h() public returns (bytes memory) { + return bytes(c); + } + + function i() public returns (uint, ActionChoices, bytes32) { + return (x, choices, st); + } +} +// ---- +// f() -> 0x20, 3, "\x03\x01\x02" +// g() -> 0x20, 3, "\x03\x01\x02" +// h() -> 0x20, 5, "hello" +// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level_standard_input.json b/examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level_standard_input.json new file mode 100644 index 00000000..5575d545 --- /dev/null +++ b/examples/test/semanticTests/constants_constant_string_at_file_level/constant_string_at_file_level_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_constant_variables/constant_variables.sol b/examples/test/semanticTests/constants_constant_variables/constant_variables.sol new file mode 100644 index 00000000..2ecd6e76 --- /dev/null +++ b/examples/test/semanticTests/constants_constant_variables/constant_variables.sol @@ -0,0 +1,8 @@ +contract Foo { + uint256 constant x = 56; + enum ActionChoices {GoLeft, GoRight, GoStraight, Sit} + ActionChoices constant choices = ActionChoices.GoLeft; + bytes32 constant st = "abc\x00\xff__"; +} +// ---- +// constructor() -> diff --git a/examples/test/semanticTests/constants_constant_variables/constant_variables_standard_input.json b/examples/test/semanticTests/constants_constant_variables/constant_variables_standard_input.json new file mode 100644 index 00000000..fa627fe6 --- /dev/null +++ b/examples/test/semanticTests/constants_constant_variables/constant_variables_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing.sol b/examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing.sol new file mode 100644 index 00000000..764ffc24 --- /dev/null +++ b/examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing.sol @@ -0,0 +1,38 @@ +==== Source: s1.sol ==== + + +bytes constant a = b; +bytes constant b = hex"030102"; + +function fre() pure returns (bytes memory) { + return a; +} + +==== Source: s2.sol ==== + +import "s1.sol"; + +uint256 constant c = uint8(a[0]) + 2; + +contract C { + function f() public returns (bytes memory) { + return a; + } + + function g() public returns (bytes memory) { + return b; + } + + function h() public returns (uint) { + return c; + } + + function i() public returns (bytes memory) { + return fre(); + } +} +// ---- +// f() -> 0x20, 3, "\x03\x01\x02" +// g() -> 0x20, 3, "\x03\x01\x02" +// h() -> 5 +// i() -> 0x20, 3, "\x03\x01\x02" diff --git a/examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing_standard_input.json b/examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing_standard_input.json new file mode 100644 index 00000000..c59dc3d3 --- /dev/null +++ b/examples/test/semanticTests/constants_constants_at_file_level_referencing/constants_at_file_level_referencing_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + }, + "constant_string.sol": { + "content": "contract C {\n bytes constant a = \"\\x03\\x01\\x02\";\n bytes constant b = hex\"030102\";\n string constant c = \"hello\";\n\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n" + }, + "constants_at_file_level_referencing.sol": { + "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (uint) {\n return c;\n }\n\n function i() public returns (bytes memory) {\n return fre();\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 5\n// i() -> 0x20, 3, \"\\x03\\x01\\x02\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_consteval_array_length/consteval_array_length.sol b/examples/test/semanticTests/constants_consteval_array_length/consteval_array_length.sol new file mode 100644 index 00000000..91e92983 --- /dev/null +++ b/examples/test/semanticTests/constants_consteval_array_length/consteval_array_length.sol @@ -0,0 +1,14 @@ +contract C { + uint constant a = 12; + uint constant b = 10; + + function f() public pure returns (uint, uint) { + uint[(a / b) * b] memory x; + return (x.length, (a / b) * b); + } +} +// ==== +// compileViaYul: true +// ---- +// constructor() -> +// f() -> 0x0a, 0x0a diff --git a/examples/test/semanticTests/constants_consteval_array_length/consteval_array_length_standard_input.json b/examples/test/semanticTests/constants_consteval_array_length/consteval_array_length_standard_input.json new file mode 100644 index 00000000..e977d9a6 --- /dev/null +++ b/examples/test/semanticTests/constants_consteval_array_length/consteval_array_length_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + }, + "constant_string.sol": { + "content": "contract C {\n bytes constant a = \"\\x03\\x01\\x02\";\n bytes constant b = hex\"030102\";\n string constant c = \"hello\";\n\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n" + }, + "constants_at_file_level_referencing.sol": { + "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (uint) {\n return c;\n }\n\n function i() public returns (bytes memory) {\n return fre();\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 5\n// i() -> 0x20, 3, \"\\x03\\x01\\x02\"\n" + }, + "same_constants_different_files.sol": { + "content": "==== Source: s1.sol ====\n\n\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport {a as b, fre} from \"s1.sol\";\nimport \"s1.sol\" as M;\n\nuint256 constant a = 13;\n\ncontract C {\n function f() public returns (uint, uint, uint, uint) {\n return (a, fre(), M.a, b);\n }\n}\n// ----\n// f() -> 0x0d, 0x59, 0x59, 0x59\n" + }, + "simple_constant_variables_test.sol": { + "content": "contract Foo {\n function getX() public returns (uint256 r) {\n return x;\n }\n\n uint256 constant x = 56;\n}\n// ----\n// getX() -> 56\n" + }, + "consteval_array_length.sol": { + "content": "contract C {\n uint constant a = 12;\n uint constant b = 10;\n\n function f() public pure returns (uint, uint) {\n uint[(a / b) * b] memory x;\n return (x.length, (a / b) * b);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// f() -> 0x0a, 0x0a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_function_unreferenced/function_unreferenced.sol b/examples/test/semanticTests/constants_function_unreferenced/function_unreferenced.sol new file mode 100644 index 00000000..d7578fec --- /dev/null +++ b/examples/test/semanticTests/constants_function_unreferenced/function_unreferenced.sol @@ -0,0 +1,9 @@ +contract B { + function g() public {} +} +contract C is B { + bytes4 constant s2 = B.g.selector; + function f() external pure returns (bytes4) { return s2; } +} +// ---- +// f() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/constants_function_unreferenced/function_unreferenced_standard_input.json b/examples/test/semanticTests/constants_function_unreferenced/function_unreferenced_standard_input.json new file mode 100644 index 00000000..6686e5ad --- /dev/null +++ b/examples/test/semanticTests/constants_function_unreferenced/function_unreferenced_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + }, + "constant_string.sol": { + "content": "contract C {\n bytes constant a = \"\\x03\\x01\\x02\";\n bytes constant b = hex\"030102\";\n string constant c = \"hello\";\n\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n" + }, + "constants_at_file_level_referencing.sol": { + "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (uint) {\n return c;\n }\n\n function i() public returns (bytes memory) {\n return fre();\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 5\n// i() -> 0x20, 3, \"\\x03\\x01\\x02\"\n" + }, + "same_constants_different_files.sol": { + "content": "==== Source: s1.sol ====\n\n\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport {a as b, fre} from \"s1.sol\";\nimport \"s1.sol\" as M;\n\nuint256 constant a = 13;\n\ncontract C {\n function f() public returns (uint, uint, uint, uint) {\n return (a, fre(), M.a, b);\n }\n}\n// ----\n// f() -> 0x0d, 0x59, 0x59, 0x59\n" + }, + "simple_constant_variables_test.sol": { + "content": "contract Foo {\n function getX() public returns (uint256 r) {\n return x;\n }\n\n uint256 constant x = 56;\n}\n// ----\n// getX() -> 56\n" + }, + "consteval_array_length.sol": { + "content": "contract C {\n uint constant a = 12;\n uint constant b = 10;\n\n function f() public pure returns (uint, uint) {\n uint[(a / b) * b] memory x;\n return (x.length, (a / b) * b);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// f() -> 0x0a, 0x0a\n" + }, + "function_unreferenced.sol": { + "content": "contract B {\n function g() public {}\n}\ncontract C is B {\n bytes4 constant s2 = B.g.selector;\n function f() external pure returns (bytes4) { return s2; }\n}\n// ----\n// f() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files.sol b/examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files.sol new file mode 100644 index 00000000..3a819bef --- /dev/null +++ b/examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files.sol @@ -0,0 +1,23 @@ +==== Source: s1.sol ==== + + +uint constant a = 89; + +function fre() pure returns (uint) { + return a; +} + +==== Source: s2.sol ==== + +import {a as b, fre} from "s1.sol"; +import "s1.sol" as M; + +uint256 constant a = 13; + +contract C { + function f() public returns (uint, uint, uint, uint) { + return (a, fre(), M.a, b); + } +} +// ---- +// f() -> 0x0d, 0x59, 0x59, 0x59 diff --git a/examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files_standard_input.json b/examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files_standard_input.json new file mode 100644 index 00000000..f3a1f15b --- /dev/null +++ b/examples/test/semanticTests/constants_same_constants_different_files/same_constants_different_files_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + }, + "constant_string.sol": { + "content": "contract C {\n bytes constant a = \"\\x03\\x01\\x02\";\n bytes constant b = hex\"030102\";\n string constant c = \"hello\";\n\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n" + }, + "constants_at_file_level_referencing.sol": { + "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (uint) {\n return c;\n }\n\n function i() public returns (bytes memory) {\n return fre();\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 5\n// i() -> 0x20, 3, \"\\x03\\x01\\x02\"\n" + }, + "same_constants_different_files.sol": { + "content": "==== Source: s1.sol ====\n\n\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport {a as b, fre} from \"s1.sol\";\nimport \"s1.sol\" as M;\n\nuint256 constant a = 13;\n\ncontract C {\n function f() public returns (uint, uint, uint, uint) {\n return (a, fre(), M.a, b);\n }\n}\n// ----\n// f() -> 0x0d, 0x59, 0x59, 0x59\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test.sol b/examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test.sol new file mode 100644 index 00000000..ed0e919f --- /dev/null +++ b/examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test.sol @@ -0,0 +1,9 @@ +contract Foo { + function getX() public returns (uint256 r) { + return x; + } + + uint256 constant x = 56; +} +// ---- +// getX() -> 56 diff --git a/examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test_standard_input.json b/examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test_standard_input.json new file mode 100644 index 00000000..67f7eed7 --- /dev/null +++ b/examples/test/semanticTests/constants_simple_constant_variables_test/simple_constant_variables_test_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "asm_address_constant_regression.sol": { + "content": "// Test for regression of https://github.com/ethereum/solidity/issues/8406\n\ncontract C {\n address constant e = 0x1212121212121212121212121000002134593163;\n\n function f() public returns (bytes1 z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x00\n" + }, + "asm_constant_file_level.sol": { + "content": "address constant e = 0x1212121212121212121212121000002134593163;\n\ncontract C {\n function f() public returns (address z) {\n assembly { z := e }\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121000002134593163\n" + }, + "constant_string_at_file_level.sol": { + "content": "bytes constant a = \"\\x03\\x01\\x02\";\nbytes constant b = hex\"030102\";\nstring constant c = \"hello\";\nuint256 constant x = 56;\nenum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\nActionChoices constant choices = ActionChoices.GoRight;\nbytes32 constant st = \"abc\\x00\\xff__\";\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n\n function i() public returns (uint, ActionChoices, bytes32) {\n return (x, choices, st);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n// i() -> 0x38, 1, 0x61626300ff5f5f00000000000000000000000000000000000000000000000000\n" + }, + "constant_variables.sol": { + "content": "contract Foo {\n uint256 constant x = 56;\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n ActionChoices constant choices = ActionChoices.GoLeft;\n bytes32 constant st = \"abc\\x00\\xff__\";\n}\n// ----\n// constructor() ->\n" + }, + "constant_string.sol": { + "content": "contract C {\n bytes constant a = \"\\x03\\x01\\x02\";\n bytes constant b = hex\"030102\";\n string constant c = \"hello\";\n\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (bytes memory) {\n return bytes(c);\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 0x20, 5, \"hello\"\n" + }, + "constants_at_file_level_referencing.sol": { + "content": "==== Source: s1.sol ====\n\n\nbytes constant a = b;\nbytes constant b = hex\"030102\";\n\nfunction fre() pure returns (bytes memory) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport \"s1.sol\";\n\nuint256 constant c = uint8(a[0]) + 2;\n\ncontract C {\n function f() public returns (bytes memory) {\n return a;\n }\n\n function g() public returns (bytes memory) {\n return b;\n }\n\n function h() public returns (uint) {\n return c;\n }\n\n function i() public returns (bytes memory) {\n return fre();\n }\n}\n// ----\n// f() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// g() -> 0x20, 3, \"\\x03\\x01\\x02\"\n// h() -> 5\n// i() -> 0x20, 3, \"\\x03\\x01\\x02\"\n" + }, + "same_constants_different_files.sol": { + "content": "==== Source: s1.sol ====\n\n\nuint constant a = 89;\n\nfunction fre() pure returns (uint) {\n return a;\n}\n\n==== Source: s2.sol ====\n\nimport {a as b, fre} from \"s1.sol\";\nimport \"s1.sol\" as M;\n\nuint256 constant a = 13;\n\ncontract C {\n function f() public returns (uint, uint, uint, uint) {\n return (a, fre(), M.a, b);\n }\n}\n// ----\n// f() -> 0x0d, 0x59, 0x59, 0x59\n" + }, + "simple_constant_variables_test.sol": { + "content": "contract Foo {\n function getX() public returns (uint256 r) {\n return x;\n }\n\n uint256 constant x = 56;\n}\n// ----\n// getX() -> 56\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors.sol b/examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors.sol new file mode 100644 index 00000000..8fe8d36f --- /dev/null +++ b/examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors.sol @@ -0,0 +1,32 @@ +contract Base { + uint public m_x; + address[] m_s; + constructor(uint x, address[] memory s) { + m_x = x; + m_s = s; + } + function part(uint i) public returns (address) { + return m_s[i]; + } +} +contract Main is Base { + constructor(address[] memory s, uint x) Base(x, f(s)) {} + function f(address[] memory s) public returns (address[] memory) { + return s; + } +} +contract Creator { + function f(uint x, address[] memory s) public returns (uint r, address ch) { + Main c = new Main(s, x); + r = c.m_x(); + ch = c.part(x); + } +} +// ---- +// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 +// gas irOptimized: 327784 +// gas irOptimized code: 94000 +// gas legacy: 336623 +// gas legacy code: 244800 +// gas legacyOptimized: 329515 +// gas legacyOptimized code: 117000 diff --git a/examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors_standard_input.json b/examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors_standard_input.json new file mode 100644 index 00000000..4e8ae3f8 --- /dev/null +++ b/examples/test/semanticTests/constructor_arrays_in_constructors/arrays_in_constructors_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments.sol b/examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments.sol new file mode 100644 index 00000000..55daf6d3 --- /dev/null +++ b/examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments.sol @@ -0,0 +1,23 @@ +contract BaseBase { + uint256 m_a; + + constructor(uint256 a) { + m_a = a; + } +} + + +contract Base is BaseBase(7) { + constructor() { + m_a *= m_a; + } +} + + +contract Derived is Base { + function getA() public returns (uint256 r) { + return m_a; + } +} +// ---- +// getA() -> 49 diff --git a/examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments_standard_input.json b/examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments_standard_input.json new file mode 100644 index 00000000..f492f877 --- /dev/null +++ b/examples/test/semanticTests/constructor_base_constructor_arguments/base_constructor_arguments_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer.sol b/examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer.sol new file mode 100644 index 00000000..69896ebf --- /dev/null +++ b/examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer.sol @@ -0,0 +1,32 @@ +contract Base { + uint public m_x; + bytes m_s; + constructor(uint x, bytes memory s) { + m_x = x; + m_s = s; + } + function part(uint i) public returns (bytes1) { + return m_s[i]; + } +} +contract Main is Base { + constructor(bytes memory s, uint x) Base(x, f(s)) {} + function f(bytes memory s) public returns (bytes memory) { + return s; + } +} +contract Creator { + function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) { + Main c = new Main(s, x); + r = c.m_x(); + ch = c.part(x); + } +} +// ---- +// f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" +// gas irOptimized: 169292 +// gas irOptimized code: 99600 +// gas legacy: 172941 +// gas legacy code: 239800 +// gas legacyOptimized: 169815 +// gas legacyOptimized code: 118600 diff --git a/examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer_standard_input.json b/examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer_standard_input.json new file mode 100644 index 00000000..df1ff11b --- /dev/null +++ b/examples/test/semanticTests/constructor_bytes_in_constructors_packer/bytes_in_constructors_packer_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker.sol b/examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker.sol new file mode 100644 index 00000000..036d6ca6 --- /dev/null +++ b/examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker.sol @@ -0,0 +1,18 @@ +contract Test { + uint public m_x; + bytes public m_s; + constructor(uint x, bytes memory s) { + m_x = x; + m_s = s; + } +} +// ---- +// constructor(): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> +// gas irOptimized: 181465 +// gas irOptimized code: 78400 +// gas legacy: 195212 +// gas legacy code: 109400 +// gas legacyOptimized: 181608 +// gas legacyOptimized code: 71400 +// m_x() -> 7 +// m_s() -> 0x20, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" diff --git a/examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker_standard_input.json b/examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker_standard_input.json new file mode 100644 index 00000000..20a9a17b --- /dev/null +++ b/examples/test/semanticTests/constructor_bytes_in_constructors_unpacker/bytes_in_constructors_unpacker_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + }, + "bytes_in_constructors_unpacker.sol": { + "content": "contract Test {\n uint public m_x;\n bytes public m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n}\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181465\n// gas irOptimized code: 78400\n// gas legacy: 195212\n// gas legacy code: 109400\n// gas legacyOptimized: 181608\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_callvalue_check/callvalue_check.sol b/examples/test/semanticTests/constructor_callvalue_check/callvalue_check.sol new file mode 100644 index 00000000..f45fbed9 --- /dev/null +++ b/examples/test/semanticTests/constructor_callvalue_check/callvalue_check.sol @@ -0,0 +1,40 @@ +contract A1 { constructor() {} } +contract B1 is A1 {} + +contract A2 { constructor() payable {} } +contract B2 is A2 {} + +contract B3 {} + +contract B4 { constructor() {} } + +contract C { + function createWithValue(bytes memory c, uint256 value) public payable returns (bool) { + uint256 y = 0; + assembly { y := create(value, add(c, 0x20), mload(c)) } + return y != 0; + } + function f(uint256 value) public payable returns (bool) { + return createWithValue(type(B1).creationCode, value); + } + function g(uint256 value) public payable returns (bool) { + return createWithValue(type(B2).creationCode, value); + } + function h(uint256 value) public payable returns (bool) { + return createWithValue(type(B3).creationCode, value); + } + function i(uint256 value) public payable returns (bool) { + return createWithValue(type(B4).creationCode, value); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f(uint256), 2000 ether: 0 -> true +// f(uint256), 2000 ether: 100 -> false +// g(uint256), 2000 ether: 0 -> true +// g(uint256), 2000 ether: 100 -> false +// h(uint256), 2000 ether: 0 -> true +// h(uint256), 2000 ether: 100 -> false +// i(uint256), 2000 ether: 0 -> true +// i(uint256), 2000 ether: 100 -> false diff --git a/examples/test/semanticTests/constructor_callvalue_check/callvalue_check_standard_input.json b/examples/test/semanticTests/constructor_callvalue_check/callvalue_check_standard_input.json new file mode 100644 index 00000000..efc880ae --- /dev/null +++ b/examples/test/semanticTests/constructor_callvalue_check/callvalue_check_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + }, + "bytes_in_constructors_unpacker.sol": { + "content": "contract Test {\n uint public m_x;\n bytes public m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n}\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181465\n// gas irOptimized code: 78400\n// gas legacy: 195212\n// gas legacy code: 109400\n// gas legacyOptimized: 181608\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n" + }, + "store_function_in_constructor_packed.sol": { + "content": "contract C {\n uint16 public result_in_constructor;\n function(uint16) returns (uint16) internal x;\n uint16 public other = 0x1fff;\n\n constructor() {\n x = doubleInv;\n result_in_constructor = use(2);\n }\n\n function doubleInv(uint16 _arg) public returns (uint16 _ret) {\n _ret = ~(_arg * 2);\n }\n\n function use(uint16 _arg) public returns (uint16) {\n return x(_arg);\n }\n}\n// ----\n// use(uint16): 3 -> 0xfff9\n// result_in_constructor() -> 0xfffb\n// other() -> 0x1fff\n" + }, + "callvalue_check.sol": { + "content": "contract A1 { constructor() {} }\ncontract B1 is A1 {}\n\ncontract A2 { constructor() payable {} }\ncontract B2 is A2 {}\n\ncontract B3 {}\n\ncontract B4 { constructor() {} }\n\ncontract C {\n\tfunction createWithValue(bytes memory c, uint256 value) public payable returns (bool) {\n\t\tuint256 y = 0;\n\t\tassembly { y := create(value, add(c, 0x20), mload(c)) }\n\t\treturn y != 0;\n\t}\n\tfunction f(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B1).creationCode, value);\n\t}\n\tfunction g(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B2).creationCode, value);\n\t}\n\tfunction h(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B3).creationCode, value);\n\t}\n\tfunction i(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B4).creationCode, value);\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256), 2000 ether: 0 -> true\n// f(uint256), 2000 ether: 100 -> false\n// g(uint256), 2000 ether: 0 -> true\n// g(uint256), 2000 ether: 100 -> false\n// h(uint256), 2000 ether: 0 -> true\n// h(uint256), 2000 ether: 100 -> false\n// i(uint256), 2000 ether: 0 -> true\n// i(uint256), 2000 ether: 100 -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external.sol b/examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external.sol new file mode 100644 index 00000000..7d068338 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external.sol @@ -0,0 +1,27 @@ +contract Main { + bytes3 name; + bool flag; + + constructor(bytes3 x, bool f) { + name = x; + flag = f; + } + + function getName() public returns (bytes3 ret) { + return name; + } + + function getFlag() public returns (bool ret) { + return flag; + } +} +// ---- +// constructor(): "abc", true +// gas irOptimized: 80174 +// gas irOptimized code: 24200 +// gas legacy: 85098 +// gas legacy code: 58200 +// gas legacyOptimized: 80132 +// gas legacyOptimized code: 22800 +// getFlag() -> true +// getName() -> "abc" diff --git a/examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external_standard_input.json b/examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external_standard_input.json new file mode 100644 index 00000000..499200f7 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_arguments_external/constructor_arguments_external_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal.sol b/examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal.sol new file mode 100644 index 00000000..bf3f0c0c --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal.sol @@ -0,0 +1,37 @@ +contract Helper { + bytes3 name; + bool flag; + + constructor(bytes3 x, bool f) { + name = x; + flag = f; + } + + function getName() public returns (bytes3 ret) { + return name; + } + + function getFlag() public returns (bool ret) { + return flag; + } +} + + +contract Main { + Helper h; + + constructor() { + h = new Helper("abc", true); + } + + function getFlag() public returns (bool ret) { + return h.getFlag(); + } + + function getName() public returns (bytes3 ret) { + return h.getName(); + } +} +// ---- +// getFlag() -> true +// getName() -> "abc" diff --git a/examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal_standard_input.json b/examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal_standard_input.json new file mode 100644 index 00000000..c79f1801 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_arguments_internal/constructor_arguments_internal_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument.sol b/examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument.sol new file mode 100644 index 00000000..159f2943 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument.sol @@ -0,0 +1,7 @@ +// The IR of this test used to throw +contract D { + constructor(function() external returns (uint)) { + } +} +// ---- +// constructor(): 0xfdd67305928fcac8d213d1e47bfa6165cd0b87b946644cd0000000000000000 -> diff --git a/examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument_standard_input.json b/examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument_standard_input.json new file mode 100644 index 00000000..190f9b6c --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_function_argument/constructor_function_argument_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + }, + "bytes_in_constructors_unpacker.sol": { + "content": "contract Test {\n uint public m_x;\n bytes public m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n}\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181465\n// gas irOptimized code: 78400\n// gas legacy: 195212\n// gas legacy code: 109400\n// gas legacyOptimized: 181608\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n" + }, + "store_function_in_constructor_packed.sol": { + "content": "contract C {\n uint16 public result_in_constructor;\n function(uint16) returns (uint16) internal x;\n uint16 public other = 0x1fff;\n\n constructor() {\n x = doubleInv;\n result_in_constructor = use(2);\n }\n\n function doubleInv(uint16 _arg) public returns (uint16 _ret) {\n _ret = ~(_arg * 2);\n }\n\n function use(uint16 _arg) public returns (uint16) {\n return x(_arg);\n }\n}\n// ----\n// use(uint16): 3 -> 0xfff9\n// result_in_constructor() -> 0xfffb\n// other() -> 0x1fff\n" + }, + "callvalue_check.sol": { + "content": "contract A1 { constructor() {} }\ncontract B1 is A1 {}\n\ncontract A2 { constructor() payable {} }\ncontract B2 is A2 {}\n\ncontract B3 {}\n\ncontract B4 { constructor() {} }\n\ncontract C {\n\tfunction createWithValue(bytes memory c, uint256 value) public payable returns (bool) {\n\t\tuint256 y = 0;\n\t\tassembly { y := create(value, add(c, 0x20), mload(c)) }\n\t\treturn y != 0;\n\t}\n\tfunction f(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B1).creationCode, value);\n\t}\n\tfunction g(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B2).creationCode, value);\n\t}\n\tfunction h(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B3).creationCode, value);\n\t}\n\tfunction i(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B4).creationCode, value);\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256), 2000 ether: 0 -> true\n// f(uint256), 2000 ether: 100 -> false\n// g(uint256), 2000 ether: 0 -> true\n// g(uint256), 2000 ether: 100 -> false\n// h(uint256), 2000 ether: 0 -> true\n// h(uint256), 2000 ether: 100 -> false\n// i(uint256), 2000 ether: 0 -> true\n// i(uint256), 2000 ether: 100 -> false\n" + }, + "functions_called_by_constructor.sol": { + "content": "contract Test {\n bytes3 name;\n bool flag;\n\n constructor() {\n setName(\"abc\");\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function setName(bytes3 _name) private {\n name = _name;\n }\n}\n// ----\n// getName() -> \"abc\"\n" + }, + "constructor_function_argument.sol": { + "content": "// The IR of this test used to throw\ncontract D {\n constructor(function() external returns (uint)) {\n }\n}\n// ----\n// constructor(): 0xfdd67305928fcac8d213d1e47bfa6165cd0b87b946644cd0000000000000000 ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex.sol b/examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex.sol new file mode 100644 index 00000000..13abe72c --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex.sol @@ -0,0 +1,21 @@ +contract D { + uint public x; + constructor(function() external pure returns (uint) g) { + x = g(); + } +} + +contract C { + function f() public returns (uint r) { + D d = new D(this.sixteen); + r = d.x(); + } + + function sixteen() public pure returns (uint) { + return 16; + } +} +// ---- +// f() -> 16 +// gas legacy: 78477 +// gas legacy code: 23600 diff --git a/examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex_standard_input.json b/examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex_standard_input.json new file mode 100644 index 00000000..d9d9d7c3 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_function_complex/constructor_function_complex_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument.sol b/examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument.sol new file mode 100644 index 00000000..5947b257 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument.sol @@ -0,0 +1,21 @@ +contract C { + uint256 public a; + uint256[3] public b; + + constructor(uint256 _a, uint256[3] memory _b) { + a = _a; + b = _b; + } +} +// ---- +// constructor(): 1, 2, 3, 4 -> +// gas irOptimized: 148129 +// gas irOptimized code: 23000 +// gas legacy: 157977 +// gas legacy code: 60400 +// gas legacyOptimized: 149973 +// gas legacyOptimized code: 26200 +// a() -> 1 +// b(uint256): 0 -> 2 +// b(uint256): 1 -> 3 +// b(uint256): 2 -> 4 diff --git a/examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument_standard_input.json b/examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument_standard_input.json new file mode 100644 index 00000000..7d3ba368 --- /dev/null +++ b/examples/test/semanticTests/constructor_constructor_static_array_argument/constructor_static_array_argument_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail.sol b/examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail.sol new file mode 100644 index 00000000..43d1fdab --- /dev/null +++ b/examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail.sol @@ -0,0 +1,18 @@ +contract A { + constructor() { + address(this).call("123"); + } +} + + +contract B { + uint256 public test = 1; + + function testIt() public { + A a = new A(); + ++test; + } +} +// ---- +// testIt() -> +// test() -> 2 diff --git a/examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail_standard_input.json b/examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail_standard_input.json new file mode 100644 index 00000000..93187b92 --- /dev/null +++ b/examples/test/semanticTests/constructor_evm_exceptions_in_constructor_call_fail/evm_exceptions_in_constructor_call_fail_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments.sol b/examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments.sol new file mode 100644 index 00000000..c04f0391 --- /dev/null +++ b/examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments.sol @@ -0,0 +1,23 @@ +contract BaseBase { + uint256 m_a; + + constructor(uint256 a) { + m_a = a; + } + + function g() public returns (uint256 r) { + return 2; + } +} + + +contract Base is BaseBase(BaseBase.g()) {} + + +contract Derived is Base { + function getA() public returns (uint256 r) { + return m_a; + } +} +// ---- +// getA() -> 2 diff --git a/examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments_standard_input.json b/examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments_standard_input.json new file mode 100644 index 00000000..08f7bd17 --- /dev/null +++ b/examples/test/semanticTests/constructor_function_usage_in_constructor_arguments/function_usage_in_constructor_arguments_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + }, + "bytes_in_constructors_unpacker.sol": { + "content": "contract Test {\n uint public m_x;\n bytes public m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n}\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181465\n// gas irOptimized code: 78400\n// gas legacy: 195212\n// gas legacy code: 109400\n// gas legacyOptimized: 181608\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n" + }, + "store_function_in_constructor_packed.sol": { + "content": "contract C {\n uint16 public result_in_constructor;\n function(uint16) returns (uint16) internal x;\n uint16 public other = 0x1fff;\n\n constructor() {\n x = doubleInv;\n result_in_constructor = use(2);\n }\n\n function doubleInv(uint16 _arg) public returns (uint16 _ret) {\n _ret = ~(_arg * 2);\n }\n\n function use(uint16 _arg) public returns (uint16) {\n return x(_arg);\n }\n}\n// ----\n// use(uint16): 3 -> 0xfff9\n// result_in_constructor() -> 0xfffb\n// other() -> 0x1fff\n" + }, + "callvalue_check.sol": { + "content": "contract A1 { constructor() {} }\ncontract B1 is A1 {}\n\ncontract A2 { constructor() payable {} }\ncontract B2 is A2 {}\n\ncontract B3 {}\n\ncontract B4 { constructor() {} }\n\ncontract C {\n\tfunction createWithValue(bytes memory c, uint256 value) public payable returns (bool) {\n\t\tuint256 y = 0;\n\t\tassembly { y := create(value, add(c, 0x20), mload(c)) }\n\t\treturn y != 0;\n\t}\n\tfunction f(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B1).creationCode, value);\n\t}\n\tfunction g(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B2).creationCode, value);\n\t}\n\tfunction h(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B3).creationCode, value);\n\t}\n\tfunction i(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B4).creationCode, value);\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256), 2000 ether: 0 -> true\n// f(uint256), 2000 ether: 100 -> false\n// g(uint256), 2000 ether: 0 -> true\n// g(uint256), 2000 ether: 100 -> false\n// h(uint256), 2000 ether: 0 -> true\n// h(uint256), 2000 ether: 100 -> false\n// i(uint256), 2000 ether: 0 -> true\n// i(uint256), 2000 ether: 100 -> false\n" + }, + "functions_called_by_constructor.sol": { + "content": "contract Test {\n bytes3 name;\n bool flag;\n\n constructor() {\n setName(\"abc\");\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function setName(bytes3 _name) private {\n name = _name;\n }\n}\n// ----\n// getName() -> \"abc\"\n" + }, + "constructor_function_argument.sol": { + "content": "// The IR of this test used to throw\ncontract D {\n constructor(function() external returns (uint)) {\n }\n}\n// ----\n// constructor(): 0xfdd67305928fcac8d213d1e47bfa6165cd0b87b946644cd0000000000000000 ->\n" + }, + "function_usage_in_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n\n function g() public returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Base is BaseBase(BaseBase.g()) {}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor.sol b/examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor.sol new file mode 100644 index 00000000..b968a07a --- /dev/null +++ b/examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor.sol @@ -0,0 +1,18 @@ +contract Test { + bytes3 name; + bool flag; + + constructor() { + setName("abc"); + } + + function getName() public returns (bytes3 ret) { + return name; + } + + function setName(bytes3 _name) private { + name = _name; + } +} +// ---- +// getName() -> "abc" diff --git a/examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor_standard_input.json b/examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor_standard_input.json new file mode 100644 index 00000000..bd5677e3 --- /dev/null +++ b/examples/test/semanticTests/constructor_functions_called_by_constructor/functions_called_by_constructor_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + }, + "bytes_in_constructors_unpacker.sol": { + "content": "contract Test {\n uint public m_x;\n bytes public m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n}\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181465\n// gas irOptimized code: 78400\n// gas legacy: 195212\n// gas legacy code: 109400\n// gas legacyOptimized: 181608\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n" + }, + "store_function_in_constructor_packed.sol": { + "content": "contract C {\n uint16 public result_in_constructor;\n function(uint16) returns (uint16) internal x;\n uint16 public other = 0x1fff;\n\n constructor() {\n x = doubleInv;\n result_in_constructor = use(2);\n }\n\n function doubleInv(uint16 _arg) public returns (uint16 _ret) {\n _ret = ~(_arg * 2);\n }\n\n function use(uint16 _arg) public returns (uint16) {\n return x(_arg);\n }\n}\n// ----\n// use(uint16): 3 -> 0xfff9\n// result_in_constructor() -> 0xfffb\n// other() -> 0x1fff\n" + }, + "callvalue_check.sol": { + "content": "contract A1 { constructor() {} }\ncontract B1 is A1 {}\n\ncontract A2 { constructor() payable {} }\ncontract B2 is A2 {}\n\ncontract B3 {}\n\ncontract B4 { constructor() {} }\n\ncontract C {\n\tfunction createWithValue(bytes memory c, uint256 value) public payable returns (bool) {\n\t\tuint256 y = 0;\n\t\tassembly { y := create(value, add(c, 0x20), mload(c)) }\n\t\treturn y != 0;\n\t}\n\tfunction f(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B1).creationCode, value);\n\t}\n\tfunction g(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B2).creationCode, value);\n\t}\n\tfunction h(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B3).creationCode, value);\n\t}\n\tfunction i(uint256 value) public payable returns (bool) {\n\t\treturn createWithValue(type(B4).creationCode, value);\n\t}\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f(uint256), 2000 ether: 0 -> true\n// f(uint256), 2000 ether: 100 -> false\n// g(uint256), 2000 ether: 0 -> true\n// g(uint256), 2000 ether: 100 -> false\n// h(uint256), 2000 ether: 0 -> true\n// h(uint256), 2000 ether: 100 -> false\n// i(uint256), 2000 ether: 0 -> true\n// i(uint256), 2000 ether: 100 -> false\n" + }, + "functions_called_by_constructor.sol": { + "content": "contract Test {\n bytes3 name;\n bool flag;\n\n constructor() {\n setName(\"abc\");\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function setName(bytes3 _name) private {\n name = _name;\n }\n}\n// ----\n// getName() -> \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch.sol b/examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch.sol new file mode 100644 index 00000000..0a1250a8 --- /dev/null +++ b/examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch.sol @@ -0,0 +1,28 @@ +contract Test { + bytes6 name; + + constructor() { + function (bytes6 _name) internal setter = setName; + setter("abcdef"); + + applyShift(leftByteShift, 3); + } + + function getName() public returns (bytes6 ret) { + return name; + } + + function setName(bytes6 _name) private { + name = _name; + } + + function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) { + return _value << _shift * 8; + } + + function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal { + name = _shiftOperator(name, _bytes); + } +} +// ---- +// getName() -> "def\x00\x00\x00" diff --git a/examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch_standard_input.json b/examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch_standard_input.json new file mode 100644 index 00000000..0124a5ff --- /dev/null +++ b/examples/test/semanticTests/constructor_functions_called_by_constructor_through_dispatch/functions_called_by_constructor_through_dispatch_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order.sol b/examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order.sol new file mode 100644 index 00000000..ef53142d --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order.sol @@ -0,0 +1,19 @@ +contract A { + uint x; + constructor() { + x = 42; + } + function f() public returns(uint256) { + return x; + } +} +contract B is A { + uint public y = f(); +} +// ==== +// compileViaYul: true +// ---- +// constructor() -> +// gas irOptimized: 99436 +// gas irOptimized code: 20200 +// y() -> 42 diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order_standard_input.json b/examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order_standard_input.json new file mode 100644 index 00000000..26793745 --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_1/constructor_inheritance_init_order_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2.sol b/examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2.sol new file mode 100644 index 00000000..d5cca642 --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2.sol @@ -0,0 +1,18 @@ +contract A { + uint x = 42; + function f() public returns(uint256) { + return x; + } +} +contract B is A { + uint public y = f(); +} +// ---- +// constructor() -> +// gas irOptimized: 99436 +// gas irOptimized code: 20200 +// gas legacy: 100973 +// gas legacy code: 32600 +// gas legacyOptimized: 99137 +// gas legacyOptimized code: 16200 +// y() -> 42 diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2_standard_input.json b/examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2_standard_input.json new file mode 100644 index 00000000..847714b1 --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_2_1/constructor_inheritance_init_order_2_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy.sol b/examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy.sol new file mode 100644 index 00000000..d9bed3f5 --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy.sol @@ -0,0 +1,12 @@ +contract A { + uint public x = 2; + constructor(uint) {} + function f() public returns(uint) { x = 4; } +} +contract B is A { + constructor() A(f()) {} +} +// ==== +// compileViaYul: false +// ---- +// x() -> 4 diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy_standard_input.json b/examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy_standard_input.json new file mode 100644 index 00000000..9cd4ce03 --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_3_legacy_1/constructor_inheritance_init_order_3_legacy_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR.sol b/examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR.sol new file mode 100644 index 00000000..0d582f8d --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR.sol @@ -0,0 +1,12 @@ +contract A { + uint public x = 2; + constructor(uint) {} + function f() public returns(uint) { x = 4; } +} +contract B is A { + constructor() A(f()) {} +} +// ==== +// compileViaYul: true +// ---- +// x() -> 2 diff --git a/examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR_standard_input.json b/examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR_standard_input.json new file mode 100644 index 00000000..a0806b3d --- /dev/null +++ b/examples/test/semanticTests/constructor_inheritance_init_order_3_viaIR_1/constructor_inheritance_init_order_3_viaIR_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor.sol b/examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor.sol new file mode 100644 index 00000000..320349cd --- /dev/null +++ b/examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor.sol @@ -0,0 +1,19 @@ +contract Base { + uint256 m_base = 5; + + function getBMember() public returns (uint256 i) { + return m_base; + } +} + + +contract Derived is Base { + uint256 m_derived = 6; + + function getDMember() public returns (uint256 i) { + return m_derived; + } +} +// ---- +// getBMember() -> 5 +// getDMember() -> 6 diff --git a/examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor_standard_input.json b/examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor_standard_input.json new file mode 100644 index 00000000..759eac1d --- /dev/null +++ b/examples/test/semanticTests/constructor_inline_member_init_inheritence_without_constructor/inline_member_init_inheritence_without_constructor_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check.sol b/examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check.sol new file mode 100644 index 00000000..583f1ca3 --- /dev/null +++ b/examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check.sol @@ -0,0 +1,25 @@ +contract A1 {} +contract B1 is A1 { constructor() payable {} } + +contract A2 { constructor() {} } +contract B2 is A2 { constructor() payable {} } + +contract B3 { constructor() payable {} } + +contract C { + function f() public payable returns (bool) { + // Make sure none of these revert. + new B1{value: 10}(); + new B2{value: 10}(); + new B3{value: 10}(); + return true; + } +} +// ---- +// f(), 2000 ether -> true +// gas irOptimized: 117623 +// gas irOptimized code: 1800 +// gas legacy: 117821 +// gas legacy code: 4800 +// gas legacyOptimized: 117690 +// gas legacyOptimized code: 4800 diff --git a/examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check_standard_input.json b/examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check_standard_input.json new file mode 100644 index 00000000..36d177dc --- /dev/null +++ b/examples/test/semanticTests/constructor_no_callvalue_check/no_callvalue_check_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation.sol b/examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation.sol new file mode 100644 index 00000000..2416f124 --- /dev/null +++ b/examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation.sol @@ -0,0 +1,22 @@ +contract A { + constructor(uint) {} +} +contract B { + constructor(uint) {} +} +contract C { + constructor(uint) {} +} +contract D { + constructor(uint) {} +} +contract X is D, C, B, A { + uint[] x; + function f(uint _x) internal returns (uint) { + x.push(_x); + } + function g() public view returns (uint[] memory) { return x; } + constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {} +} +// ---- +// g() -> 0x20, 4, 1, 3, 2, 4 diff --git a/examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation_standard_input.json b/examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation_standard_input.json new file mode 100644 index 00000000..df223719 --- /dev/null +++ b/examples/test/semanticTests/constructor_order_of_evaluation/order_of_evaluation_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_payable_constructor/payable_constructor.sol b/examples/test/semanticTests/constructor_payable_constructor/payable_constructor.sol new file mode 100644 index 00000000..09fe0a1c --- /dev/null +++ b/examples/test/semanticTests/constructor_payable_constructor/payable_constructor.sol @@ -0,0 +1,5 @@ +contract C { + constructor() payable {} +} +// ---- +// constructor(), 27 wei -> diff --git a/examples/test/semanticTests/constructor_payable_constructor/payable_constructor_standard_input.json b/examples/test/semanticTests/constructor_payable_constructor/payable_constructor_standard_input.json new file mode 100644 index 00000000..954a3660 --- /dev/null +++ b/examples/test/semanticTests/constructor_payable_constructor/payable_constructor_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor.sol b/examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor.sol new file mode 100644 index 00000000..dee3af35 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor.sol @@ -0,0 +1,20 @@ +contract C { + uint256 public result_in_constructor; + function(uint256) returns (uint256) internal x; + + constructor() { + x = double; + result_in_constructor = use(2); + } + + function double(uint256 _arg) public returns (uint256 _ret) { + _ret = _arg * 2; + } + + function use(uint256 _arg) public returns (uint256) { + return x(_arg); + } +} +// ---- +// use(uint256): 3 -> 6 +// result_in_constructor() -> 4 diff --git a/examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor_standard_input.json b/examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor_standard_input.json new file mode 100644 index 00000000..592c9740 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_function_in_constructor/store_function_in_constructor_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed.sol b/examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed.sol new file mode 100644 index 00000000..07b12ad9 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed.sol @@ -0,0 +1,22 @@ +contract C { + uint16 public result_in_constructor; + function(uint16) returns (uint16) internal x; + uint16 public other = 0x1fff; + + constructor() { + x = doubleInv; + result_in_constructor = use(2); + } + + function doubleInv(uint16 _arg) public returns (uint16 _ret) { + _ret = ~(_arg * 2); + } + + function use(uint16 _arg) public returns (uint16) { + return x(_arg); + } +} +// ---- +// use(uint16): 3 -> 0xfff9 +// result_in_constructor() -> 0xfffb +// other() -> 0x1fff diff --git a/examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed_standard_input.json b/examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed_standard_input.json new file mode 100644 index 00000000..23426e98 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_function_in_constructor_packed/store_function_in_constructor_packed_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "bytes_in_constructors_packer.sol": { + "content": "contract Base {\n uint public m_x;\n bytes m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (bytes1) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(bytes memory s, uint x) Base(x, f(s)) {}\n function f(bytes memory s) public returns (bytes memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, bytes memory s) public returns (uint r, bytes1 ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,bytes): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" -> 7, \"h\"\n// gas irOptimized: 169292\n// gas irOptimized code: 99600\n// gas legacy: 172941\n// gas legacy code: 239800\n// gas legacyOptimized: 169815\n// gas legacyOptimized code: 118600\n" + }, + "bytes_in_constructors_unpacker.sol": { + "content": "contract Test {\n uint public m_x;\n bytes public m_s;\n constructor(uint x, bytes memory s) {\n m_x = x;\n m_s = s;\n }\n}\n// ----\n// constructor(): 7, 0x40, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\" ->\n// gas irOptimized: 181465\n// gas irOptimized code: 78400\n// gas legacy: 195212\n// gas legacy code: 109400\n// gas legacyOptimized: 181608\n// gas legacyOptimized code: 71400\n// m_x() -> 7\n// m_s() -> 0x20, 78, \"abcdefghijklmnopqrstuvwxyzabcdef\", \"ghijklmnopqrstuvwxyzabcdefghijkl\", \"mnopqrstuvwxyz\"\n" + }, + "store_function_in_constructor_packed.sol": { + "content": "contract C {\n uint16 public result_in_constructor;\n function(uint16) returns (uint16) internal x;\n uint16 public other = 0x1fff;\n\n constructor() {\n x = doubleInv;\n result_in_constructor = use(2);\n }\n\n function doubleInv(uint16 _arg) public returns (uint16 _ret) {\n _ret = ~(_arg * 2);\n }\n\n function use(uint16 _arg) public returns (uint16) {\n return x(_arg);\n }\n}\n// ----\n// use(uint16): 3 -> 0xfff9\n// result_in_constructor() -> 0xfffb\n// other() -> 0x1fff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor.sol b/examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor.sol new file mode 100644 index 00000000..cc9d8ca6 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor.sol @@ -0,0 +1,17 @@ +contract C { + function() returns (uint256) internal x; + + constructor() { + x = unused; + } + + function unused() internal returns (uint256) { + return 7; + } + + function t() public returns (uint256) { + return x(); + } +} +// ---- +// t() -> 7 diff --git a/examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor_standard_input.json b/examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor_standard_input.json new file mode 100644 index 00000000..e2906036 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_internal_unused_function_in_constructor/store_internal_unused_function_in_constructor_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor.sol b/examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor.sol new file mode 100644 index 00000000..5845e9b5 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor.sol @@ -0,0 +1,20 @@ +library L { + function x() internal returns (uint256) { + return 7; + } +} + + +contract C { + function() returns (uint256) internal x; + + constructor() { + x = L.x; + } + + function t() public returns (uint256) { + return x(); + } +} +// ---- +// t() -> 7 diff --git a/examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor_standard_input.json b/examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor_standard_input.json new file mode 100644 index 00000000..2d85add5 --- /dev/null +++ b/examples/test/semanticTests/constructor_store_internal_unused_library_function_in_constructor/store_internal_unused_library_function_in_constructor_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "constructor_arguments_internal.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() {\n h = new Helper(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n}\n// ----\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "order_of_evaluation.sol": { + "content": "contract A {\n constructor(uint) {}\n}\ncontract B {\n constructor(uint) {}\n}\ncontract C {\n constructor(uint) {}\n}\ncontract D {\n constructor(uint) {}\n}\ncontract X is D, C, B, A {\n uint[] x;\n function f(uint _x) internal returns (uint) {\n x.push(_x);\n }\n function g() public view returns (uint[] memory) { return x; }\n constructor() A(f(1)) C(f(2)) B(f(3)) D(f(4)) {}\n}\n// ----\n// g() -> 0x20, 4, 1, 3, 2, 4\n" + }, + "payable_constructor.sol": { + "content": "contract C {\n constructor() payable {}\n}\n// ----\n// constructor(), 27 wei ->\n" + }, + "constructor_static_array_argument.sol": { + "content": "contract C {\n uint256 public a;\n uint256[3] public b;\n\n constructor(uint256 _a, uint256[3] memory _b) {\n a = _a;\n b = _b;\n }\n}\n// ----\n// constructor(): 1, 2, 3, 4 ->\n// gas irOptimized: 148129\n// gas irOptimized code: 23000\n// gas legacy: 157977\n// gas legacy code: 60400\n// gas legacyOptimized: 149973\n// gas legacyOptimized code: 26200\n// a() -> 1\n// b(uint256): 0 -> 2\n// b(uint256): 1 -> 3\n// b(uint256): 2 -> 4\n" + }, + "no_callvalue_check.sol": { + "content": "contract A1 {}\ncontract B1 is A1 { constructor() payable {} }\n\ncontract A2 { constructor() {} }\ncontract B2 is A2 { constructor() payable {} }\n\ncontract B3 { constructor() payable {} }\n\ncontract C {\n\tfunction f() public payable returns (bool) {\n\t\t// Make sure none of these revert.\n\t\tnew B1{value: 10}();\n\t\tnew B2{value: 10}();\n\t\tnew B3{value: 10}();\n\t\treturn true;\n\t}\n}\n// ----\n// f(), 2000 ether -> true\n// gas irOptimized: 117623\n// gas irOptimized code: 1800\n// gas legacy: 117821\n// gas legacy code: 4800\n// gas legacyOptimized: 117690\n// gas legacyOptimized code: 4800\n" + }, + "store_internal_unused_function_in_constructor.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = unused;\n }\n\n function unused() internal returns (uint256) {\n return 7;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + }, + "constructor_function_complex.sol": { + "content": "contract D {\n uint public x;\n constructor(function() external pure returns (uint) g) {\n x = g();\n }\n}\n\ncontract C {\n function f() public returns (uint r) {\n D d = new D(this.sixteen);\n r = d.x();\n }\n\n function sixteen() public pure returns (uint) {\n return 16;\n }\n}\n// ----\n// f() -> 16\n// gas legacy: 78477\n// gas legacy code: 23600\n" + }, + "functions_called_by_constructor_through_dispatch.sol": { + "content": "contract Test {\n bytes6 name;\n\n constructor() {\n function (bytes6 _name) internal setter = setName;\n setter(\"abcdef\");\n\n applyShift(leftByteShift, 3);\n }\n\n function getName() public returns (bytes6 ret) {\n return name;\n }\n\n function setName(bytes6 _name) private {\n name = _name;\n }\n\n function leftByteShift(bytes6 _value, uint _shift) public returns (bytes6) {\n return _value << _shift * 8;\n }\n\n function applyShift(function (bytes6 _value, uint _shift) internal returns (bytes6) _shiftOperator, uint _bytes) internal {\n name = _shiftOperator(name, _bytes);\n }\n}\n// ----\n// getName() -> \"def\\x00\\x00\\x00\"\n" + }, + "evm_exceptions_in_constructor_call_fail.sol": { + "content": "contract A {\n constructor() {\n address(this).call(\"123\");\n }\n}\n\n\ncontract B {\n uint256 public test = 1;\n\n function testIt() public {\n A a = new A();\n ++test;\n }\n}\n// ----\n// testIt() ->\n// test() -> 2\n" + }, + "store_function_in_constructor.sol": { + "content": "contract C {\n uint256 public result_in_constructor;\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n result_in_constructor = use(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function use(uint256 _arg) public returns (uint256) {\n return x(_arg);\n }\n}\n// ----\n// use(uint256): 3 -> 6\n// result_in_constructor() -> 4\n" + }, + "constructor_arguments_external.sol": { + "content": "contract Main {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n// ----\n// constructor(): \"abc\", true\n// gas irOptimized: 80174\n// gas irOptimized code: 24200\n// gas legacy: 85098\n// gas legacy code: 58200\n// gas legacyOptimized: 80132\n// gas legacyOptimized code: 22800\n// getFlag() -> true\n// getName() -> \"abc\"\n" + }, + "inline_member_init_inheritence_without_constructor.sol": { + "content": "contract Base {\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "base_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n}\n\n\ncontract Base is BaseBase(7) {\n constructor() {\n m_a *= m_a;\n }\n}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n}\n// ----\n// getA() -> 49\n" + }, + "store_internal_unused_library_function_in_constructor.sol": { + "content": "library L {\n function x() internal returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function() returns (uint256) internal x;\n\n constructor() {\n x = L.x;\n }\n\n function t() public returns (uint256) {\n return x();\n }\n}\n// ----\n// t() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization.sol b/examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization.sol new file mode 100644 index 00000000..3260fa30 --- /dev/null +++ b/examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization.sol @@ -0,0 +1,18 @@ +contract C { + uint128 transient x; + uint128 y; + + constructor() { + x = 100; + y = x; + } + + function f() external view returns (uint128) { + return y; + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 100 diff --git a/examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization_standard_input.json b/examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization_standard_input.json new file mode 100644 index 00000000..1084d23c --- /dev/null +++ b/examples/test/semanticTests/constructor_transient_state_variable_initialization/transient_state_variable_initialization_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "arrays_in_constructors.sol": { + "content": "contract Base {\n uint public m_x;\n address[] m_s;\n constructor(uint x, address[] memory s) {\n m_x = x;\n m_s = s;\n }\n function part(uint i) public returns (address) {\n return m_s[i];\n }\n}\ncontract Main is Base {\n constructor(address[] memory s, uint x) Base(x, f(s)) {}\n function f(address[] memory s) public returns (address[] memory) {\n return s;\n }\n}\ncontract Creator {\n function f(uint x, address[] memory s) public returns (uint r, address ch) {\n Main c = new Main(s, x);\n r = c.m_x();\n ch = c.part(x);\n }\n}\n// ----\n// f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8\n// gas irOptimized: 327784\n// gas irOptimized code: 94000\n// gas legacy: 336623\n// gas legacy code: 244800\n// gas legacyOptimized: 329515\n// gas legacyOptimized code: 117000\n" + }, + "transient_state_variable_initialization.sol": { + "content": "contract C {\n uint128 transient x;\n uint128 y;\n\n constructor() {\n x = 100;\n y = x;\n }\n\n function f() external view returns (uint128) {\n return y;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_with_params_1/constructor_with_params.sol b/examples/test/semanticTests/constructor_with_params_1/constructor_with_params.sol new file mode 100644 index 00000000..c8880202 --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_1/constructor_with_params.sol @@ -0,0 +1,17 @@ +contract C { + uint public i; + uint public k; + + constructor(uint newI, uint newK) { + i = newI; + k = newK; + } +} +// ---- +// constructor(): 2, 0 -> +// gas irOptimized: 81170 +// gas irOptimized code: 20200 +// gas legacy: 83613 +// gas legacy code: 32000 +// i() -> 2 +// k() -> 0 diff --git a/examples/test/semanticTests/constructor_with_params_1/constructor_with_params_standard_input.json b/examples/test/semanticTests/constructor_with_params_1/constructor_with_params_standard_input.json new file mode 100644 index 00000000..e605231c --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_1/constructor_with_params_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance.sol b/examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance.sol new file mode 100644 index 00000000..decb6fc2 --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance.sol @@ -0,0 +1,32 @@ +contract A { + uint public i; + uint public k; + + constructor(uint newI, uint newK) { + i = newI; + k = newK; + } +} +abstract contract B is A { + uint public j; + constructor(uint newJ) { + j = newJ; + } +} +contract C is A { + constructor(uint newI, uint newK) A(newI, newK) {} +} +contract D is B, C { + constructor(uint newI, uint newK) B(newI) C(newI, newK + 1) {} +} +// ---- +// constructor(): 2, 0 -> +// gas irOptimized: 124350 +// gas irOptimized code: 27600 +// gas legacy: 128222 +// gas legacy code: 40400 +// gas legacyOptimized: 123920 +// gas legacyOptimized code: 20600 +// i() -> 2 +// j() -> 2 +// k() -> 1 diff --git a/examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance_standard_input.json b/examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance_standard_input.json new file mode 100644 index 00000000..627e6bc1 --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_diamond_inheritance_1/constructor_with_params_diamond_inheritance_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + }, + "c99_scoping_activation.sol": { + "content": "contract test {\n function f() pure public returns (uint) {\n uint x = 7;\n {\n x = 3; // This should still assign to the outer variable\n uint x;\n x = 4; // This should assign to the new one\n }\n return x;\n }\n function g() pure public returns (uint x) {\n x = 7;\n {\n x = 3;\n uint x;\n return x; // This returns the new variable, i.e. 0\n }\n }\n function h() pure public returns (uint x, uint a, uint b) {\n x = 7;\n {\n x = 3;\n a = x; // This should read from the outer\n uint x = 4;\n b = x;\n }\n }\n function i() pure public returns (uint x, uint a) {\n x = 7;\n {\n x = 3;\n uint x = x; // This should read from the outer and assign to the inner\n a = x;\n }\n }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n" + }, + "empty_contract.sol": { + "content": "contract test {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// i_am_not_there() -> FAILURE\n" + }, + "dirty_calldata_bytes.sol": { + "content": "contract C {\n function f(bytes calldata b) public returns (bool correct) {\n bytes1 a = b[3];\n uint r;\n assembly {\n r := a\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f(bytes): 0x20, 0x04, \"dead\" -> true\n" + }, + "state_var_initialization.sol": { + "content": "contract C {\n uint public i = 1;\n uint public k = 2;\n\n constructor() {\n i = i + i;\n k = k - i;\n }\n}\n// ----\n// i() -> 2\n// k() -> 0\n" + }, + "interface_inheritance_conversions.sol": { + "content": "interface Parent {\n function parentFun() external returns (uint256);\n}\n\ninterface SubA is Parent {\n function subAFun() external returns (uint256);\n}\n\ninterface SubB is Parent {\n function subBFun() external returns (uint256);\n}\n\ncontract Impl is SubA, SubB {\n function parentFun() override external returns (uint256) { return 1; }\n function subAFun() override external returns (uint256) { return 2; }\n function subBFun() override external returns (uint256) { return 3; }\n}\n\ncontract C {\n function convertParent() public returns (uint256) {\n Parent p = new Impl();\n return p.parentFun();\n }\n\n function convertSubA() public returns (uint256, uint256) {\n SubA sa = new Impl();\n return (sa.parentFun(), sa.subAFun());\n }\n\n function convertSubB() public returns (uint256, uint256) {\n SubB sb = new Impl();\n return (sb.parentFun(), sb.subBFun());\n }\n}\n// ----\n// convertParent() -> 1\n// gas irOptimized: 85524\n// convertSubA() -> 1, 2\n// gas irOptimized: 86155\n// gas legacy: 99047\n// convertSubB() -> 1, 3\n// gas irOptimized: 86098\n// gas legacy: 98981\n" + }, + "constructor_with_params_diamond_inheritance.sol": { + "content": "contract A {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\nabstract contract B is A {\n uint public j;\n constructor(uint newJ) {\n j = newJ;\n }\n}\ncontract C is A {\n constructor(uint newI, uint newK) A(newI, newK) {}\n}\ncontract D is B, C {\n constructor(uint newI, uint newK) B(newI) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 124350\n// gas irOptimized code: 27600\n// gas legacy: 128222\n// gas legacy code: 40400\n// gas legacyOptimized: 123920\n// gas legacyOptimized code: 20600\n// i() -> 2\n// j() -> 2\n// k() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance.sol b/examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance.sol new file mode 100644 index 00000000..097e2f80 --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance.sol @@ -0,0 +1,22 @@ +contract C { + uint public i; + uint public k; + + constructor(uint newI, uint newK) { + i = newI; + k = newK; + } +} +contract D is C { + constructor(uint newI, uint newK) C(newI, newK + 1) {} +} +// ---- +// constructor(): 2, 0 -> +// gas irOptimized: 101581 +// gas irOptimized code: 20200 +// gas legacy: 105192 +// gas legacy code: 32000 +// gas legacyOptimized: 101503 +// gas legacyOptimized code: 17000 +// i() -> 2 +// k() -> 1 diff --git a/examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance_standard_input.json b/examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance_standard_input.json new file mode 100644 index 00000000..a6d0a789 --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_inheritance_1/constructor_with_params_inheritance_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2.sol b/examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2.sol new file mode 100644 index 00000000..8a9fc03a --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2.sol @@ -0,0 +1,13 @@ +contract C { + uint public i; + uint public k; + + constructor(uint newI, uint newK) { + i = newI; + k = newK; + } +} +contract D is C(2, 1) {} +// ---- +// i() -> 2 +// k() -> 1 diff --git a/examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2_standard_input.json b/examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2_standard_input.json new file mode 100644 index 00000000..adff3740 --- /dev/null +++ b/examples/test/semanticTests/constructor_with_params_inheritance_2_1/constructor_with_params_inheritance_2_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage.sol b/examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage.sol new file mode 100644 index 00000000..94dc0307 --- /dev/null +++ b/examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage.sol @@ -0,0 +1,42 @@ +contract C { + function () external returns(uint)[1] externalDefaultArray; + function () external view returns(uint)[1] externalViewArray; + function () external pure returns(uint)[1] externalPureArray; + + function () internal returns(uint)[1] internalDefaultArray; + function () internal view returns(uint)[1] internalViewArray; + function () internal pure returns(uint)[1] internalPureArray; + + function externalDefault() external returns(uint) { return 11; } + function externalView() external view returns(uint) { return 12; } + function externalPure() external pure returns(uint) { return 13; } + + function internalDefault() internal returns(uint) { return 21; } + function internalView() internal view returns(uint) { return 22; } + function internalPure() internal pure returns(uint) { return 23; } + + function testViewToDefault() public returns (uint, uint) { + externalDefaultArray = [this.externalView]; + internalDefaultArray = [internalView]; + + return (externalDefaultArray[0](), internalDefaultArray[0]()); + } + + function testPureToDefault() public returns (uint, uint) { + externalDefaultArray = [this.externalPure]; + internalDefaultArray = [internalPure]; + + return (externalDefaultArray[0](), internalDefaultArray[0]()); + } + + function testPureToView() public returns (uint, uint) { + externalViewArray = [this.externalPure]; + internalViewArray = [internalPure]; + + return (externalViewArray[0](), internalViewArray[0]()); + } +} +// ---- +// testViewToDefault() -> 12, 22 +// testPureToDefault() -> 13, 23 +// testPureToView() -> 13, 23 diff --git a/examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage_standard_input.json b/examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage_standard_input.json new file mode 100644 index 00000000..299b1025 --- /dev/null +++ b/examples/test/semanticTests/conversions_function_type_array_to_storage/function_type_array_to_storage_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "function_type_array_to_storage.sol": { + "content": "contract C {\n function () external returns(uint)[1] externalDefaultArray;\n function () external view returns(uint)[1] externalViewArray;\n function () external pure returns(uint)[1] externalPureArray;\n\n function () internal returns(uint)[1] internalDefaultArray;\n function () internal view returns(uint)[1] internalViewArray;\n function () internal pure returns(uint)[1] internalPureArray;\n\n function externalDefault() external returns(uint) { return 11; }\n function externalView() external view returns(uint) { return 12; }\n function externalPure() external pure returns(uint) { return 13; }\n\n function internalDefault() internal returns(uint) { return 21; }\n function internalView() internal view returns(uint) { return 22; }\n function internalPure() internal pure returns(uint) { return 23; }\n\n function testViewToDefault() public returns (uint, uint) {\n externalDefaultArray = [this.externalView];\n internalDefaultArray = [internalView];\n\n return (externalDefaultArray[0](), internalDefaultArray[0]());\n }\n\n function testPureToDefault() public returns (uint, uint) {\n externalDefaultArray = [this.externalPure];\n internalDefaultArray = [internalPure];\n\n return (externalDefaultArray[0](), internalDefaultArray[0]());\n }\n\n function testPureToView() public returns (uint, uint) {\n externalViewArray = [this.externalPure];\n internalViewArray = [internalPure];\n\n return (externalViewArray[0](), internalViewArray[0]());\n }\n}\n// ----\n// testViewToDefault() -> 12, 22\n// testPureToDefault() -> 13, 23\n// testPureToView() -> 13, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes.sol b/examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes.sol new file mode 100644 index 00000000..2f324588 --- /dev/null +++ b/examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes.sol @@ -0,0 +1,7 @@ +contract C { + function f(string memory s) public pure returns (bytes memory t) { + t = bytes(s); + } +} +// ---- +// f(string): 32, 5, "Hello" -> 32, 5, "Hello" diff --git a/examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes_standard_input.json b/examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes_standard_input.json new file mode 100644 index 00000000..cad19662 --- /dev/null +++ b/examples/test/semanticTests/conversions_string_to_bytes/string_to_bytes_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "function_type_array_to_storage.sol": { + "content": "contract C {\n function () external returns(uint)[1] externalDefaultArray;\n function () external view returns(uint)[1] externalViewArray;\n function () external pure returns(uint)[1] externalPureArray;\n\n function () internal returns(uint)[1] internalDefaultArray;\n function () internal view returns(uint)[1] internalViewArray;\n function () internal pure returns(uint)[1] internalPureArray;\n\n function externalDefault() external returns(uint) { return 11; }\n function externalView() external view returns(uint) { return 12; }\n function externalPure() external pure returns(uint) { return 13; }\n\n function internalDefault() internal returns(uint) { return 21; }\n function internalView() internal view returns(uint) { return 22; }\n function internalPure() internal pure returns(uint) { return 23; }\n\n function testViewToDefault() public returns (uint, uint) {\n externalDefaultArray = [this.externalView];\n internalDefaultArray = [internalView];\n\n return (externalDefaultArray[0](), internalDefaultArray[0]());\n }\n\n function testPureToDefault() public returns (uint, uint) {\n externalDefaultArray = [this.externalPure];\n internalDefaultArray = [internalPure];\n\n return (externalDefaultArray[0](), internalDefaultArray[0]());\n }\n\n function testPureToView() public returns (uint, uint) {\n externalViewArray = [this.externalPure];\n internalViewArray = [internalPure];\n\n return (externalViewArray[0](), internalViewArray[0]());\n }\n}\n// ----\n// testViewToDefault() -> 12, 22\n// testPureToDefault() -> 13, 23\n// testPureToView() -> 13, 23\n" + }, + "string_to_bytes.sol": { + "content": "contract C {\n\tfunction f(string memory s) public pure returns (bytes memory t) {\n\t\tt = bytes(s);\n\t}\n}\n// ----\n// f(string): 32, 5, \"Hello\" -> 32, 5, \"Hello\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function.sol b/examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function.sol new file mode 100644 index 00000000..64b80422 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function.sol @@ -0,0 +1,40 @@ +function longdata(S memory) pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function_standard_input.json new file mode 100644 index 00000000..4d3a78a9 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_bound_function/bound_function_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_library_function/library_function.sol b/examples/test/semanticTests/deployedCodeExclusion_library_function/library_function.sol new file mode 100644 index 00000000..93110919 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_library_function/library_function.sol @@ -0,0 +1,34 @@ +library L { + function longdata() pure internal returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_library_function/library_function_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_library_function/library_function_standard_input.json new file mode 100644 index 00000000..f2c6d71a --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_library_function/library_function_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "library_function.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed.sol b/examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed.sol new file mode 100644 index 00000000..30f403af --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed.sol @@ -0,0 +1,31 @@ +library L { + function longdata() pure internal returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed_standard_input.json new file mode 100644 index 00000000..01abfc72 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_library_function_deployed/library_function_deployed_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_module_function/module_function.sol b/examples/test/semanticTests/deployedCodeExclusion_module_function/module_function.sol new file mode 100644 index 00000000..018d4105 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_module_function/module_function.sol @@ -0,0 +1,36 @@ +==== Source: mod.sol ==== +function longdata() pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_module_function/module_function_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_module_function/module_function_standard_input.json new file mode 100644 index 00000000..d0430274 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_module_function/module_function_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "library_function.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "subassembly_deduplication.sol": { + "content": "contract A {\n function longdata() pure external returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "module_function_deployed.sol": { + "content": "==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "module_function.sol": { + "content": "==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed.sol b/examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed.sol new file mode 100644 index 00000000..f29355e0 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed.sol @@ -0,0 +1,32 @@ +==== Source: mod.sol ==== +function longdata() pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed_standard_input.json new file mode 100644 index 00000000..521021ec --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_module_function_deployed/module_function_deployed_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "library_function.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "subassembly_deduplication.sol": { + "content": "contract A {\n function longdata() pure external returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "module_function_deployed.sol": { + "content": "==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function.sol b/examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function.sol new file mode 100644 index 00000000..0f9b023b --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function.sol @@ -0,0 +1,35 @@ +abstract contract S { + function longdata() internal pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function_standard_input.json new file mode 100644 index 00000000..4df0c2c7 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_static_base_function/static_base_function_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed.sol b/examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed.sol new file mode 100644 index 00000000..a7c8d6cf --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed.sol @@ -0,0 +1,31 @@ +abstract contract S { + function longdata() internal pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed_standard_input.json new file mode 100644 index 00000000..7a1a81be --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_static_base_function_deployed/static_base_function_deployed_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication.sol b/examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication.sol new file mode 100644 index 00000000..b6ae85b8 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication.sol @@ -0,0 +1,41 @@ +contract A { + function longdata() pure external returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication_standard_input.json new file mode 100644 index 00000000..0bb86f0a --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_subassembly_deduplication/subassembly_deduplication_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "library_function.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "subassembly_deduplication.sol": { + "content": "contract A {\n function longdata() pure external returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_super_function/super_function.sol b/examples/test/semanticTests/deployedCodeExclusion_super_function/super_function.sol new file mode 100644 index 00000000..9accc54a --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_super_function/super_function.sol @@ -0,0 +1,35 @@ +abstract contract S { + function longdata() internal pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_super_function/super_function_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_super_function/super_function_standard_input.json new file mode 100644 index 00000000..e467c5e2 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_super_function/super_function_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed.sol b/examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed.sol new file mode 100644 index 00000000..9588007b --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed.sol @@ -0,0 +1,31 @@ +abstract contract S { + function longdata() internal pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed_standard_input.json new file mode 100644 index 00000000..704e5fa0 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_super_function_deployed/super_function_deployed_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "library_function.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "subassembly_deduplication.sol": { + "content": "contract A {\n function longdata() pure external returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "module_function_deployed.sol": { + "content": "==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "module_function.sol": { + "content": "==== Source: mod.sol ====\nfunction longdata() pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function.sol b/examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function.sol new file mode 100644 index 00000000..866fe9df --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function.sol @@ -0,0 +1,39 @@ +abstract contract S { + function longdata() internal virtual pure returns (bytes memory); +} + +abstract contract X is S { + function longdata() internal override pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function_standard_input.json new file mode 100644 index 00000000..e5720871 --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_virtual_function/virtual_function_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed.sol b/examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed.sol new file mode 100644 index 00000000..bcc95b9f --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed.sol @@ -0,0 +1,35 @@ +abstract contract S { + function longdata() internal virtual pure returns (bytes memory); +} + +abstract contract X is S { + function longdata() internal override pure returns (bytes memory) { + return + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID" + "M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI" + "AJMO true diff --git a/examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed_standard_input.json b/examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed_standard_input.json new file mode 100644 index 00000000..406d4fce --- /dev/null +++ b/examples/test/semanticTests/deployedCodeExclusion_virtual_function_deployed/virtual_function_deployed_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "library_function_deployed.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "bound_function.sol": { + "content": "function longdata(S memory) pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "super_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "static_base_function.sol": { + "content": "abstract contract S {\n function longdata() internal pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "library_function.sol": { + "content": "library L {\n function longdata() pure internal returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "subassembly_deduplication.sol": { + "content": "contract A {\n function longdata() pure external returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + }, + "virtual_function_deployed.sol": { + "content": "abstract contract S {\n function longdata() internal virtual pure returns (bytes memory);\n}\n\nabstract contract X is S {\n function longdata() internal override pure returns (bytes memory) {\n return\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"xasopca.pngaibngidak.jbtnudak.cAP.BRRSMCPJAGPD KIAJDOMHUKR,SCPID\"\n \"M,SEYBDXCNTKIMNJGO;DUIAQBQUEHAKMPGIDSAJCOUKANJBCUEBKNA.GIAKMV.TI\"\n \"AJMO true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes.sol b/examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes.sol new file mode 100644 index 00000000..5876b1f7 --- /dev/null +++ b/examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes.sol @@ -0,0 +1,12 @@ +contract C { + function f(bytes calldata b) public returns (bool correct) { + bytes1 a = b[3]; + uint r; + assembly { + r := a + } + correct = r == (0x64 << 248); + } +} +// ---- +// f(bytes): 0x20, 0x04, "dead" -> true diff --git a/examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes_standard_input.json b/examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes_standard_input.json new file mode 100644 index 00000000..6235bce0 --- /dev/null +++ b/examples/test/semanticTests/dirty_calldata_bytes_1/dirty_calldata_bytes_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + }, + "c99_scoping_activation.sol": { + "content": "contract test {\n function f() pure public returns (uint) {\n uint x = 7;\n {\n x = 3; // This should still assign to the outer variable\n uint x;\n x = 4; // This should assign to the new one\n }\n return x;\n }\n function g() pure public returns (uint x) {\n x = 7;\n {\n x = 3;\n uint x;\n return x; // This returns the new variable, i.e. 0\n }\n }\n function h() pure public returns (uint x, uint a, uint b) {\n x = 7;\n {\n x = 3;\n a = x; // This should read from the outer\n uint x = 4;\n b = x;\n }\n }\n function i() pure public returns (uint x, uint a) {\n x = 7;\n {\n x = 3;\n uint x = x; // This should read from the outer and assign to the inner\n a = x;\n }\n }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n" + }, + "empty_contract.sol": { + "content": "contract test {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// i_am_not_there() -> FAILURE\n" + }, + "dirty_calldata_bytes.sol": { + "content": "contract C {\n function f(bytes calldata b) public returns (bool correct) {\n bytes1 a = b[3];\n uint r;\n assembly {\n r := a\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f(bytes): 0x20, 0x04, \"dead\" -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array.sol b/examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array.sol new file mode 100644 index 00000000..b59eb922 --- /dev/null +++ b/examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array.sol @@ -0,0 +1,12 @@ +contract C { + function f(int16[] calldata a) external returns (bool correct) { + uint32 x = uint32(uint16(a[1])); + uint r; + assembly { + r := x + } + correct = r == 0x7fff; + } +} +// ---- +// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true diff --git a/examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array_standard_input.json b/examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array_standard_input.json new file mode 100644 index 00000000..af9e0b8f --- /dev/null +++ b/examples/test/semanticTests/dirty_calldata_dynamic_array_1/dirty_calldata_dynamic_array_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/ecrecover_ecrecover/ecrecover.sol b/examples/test/semanticTests/ecrecover_ecrecover/ecrecover.sol new file mode 100644 index 00000000..1beb451d --- /dev/null +++ b/examples/test/semanticTests/ecrecover_ecrecover/ecrecover.sol @@ -0,0 +1,12 @@ +contract test { + function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) { + return ecrecover(h, v, r, s); + } +} +// ---- +// a(bytes32,uint8,bytes32,bytes32): +// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, +// 28, +// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, +// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549 +// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b diff --git a/examples/test/semanticTests/ecrecover_ecrecover/ecrecover_standard_input.json b/examples/test/semanticTests/ecrecover_ecrecover/ecrecover_standard_input.json new file mode 100644 index 00000000..3be5b31e --- /dev/null +++ b/examples/test/semanticTests/ecrecover_ecrecover/ecrecover_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "ecrecover_abiV2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n return ecrecover(h, v, r, s);\n }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n" + }, + "failing_ecrecover_invalid_input_asm.sol": { + "content": "contract C {\n function f() public returns (address) {\n assembly {\n mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c)\n }\n return ecrecover(\n 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n 0, // invalid v value\n 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d\n );\n }\n}\n// ----\n// f() -> 0\n" + }, + "failing_ecrecover_invalid_input.sol": { + "content": "contract C {\n // ecrecover should return zero for malformed input\n\t// (v should be 27 or 28, not 1)\n\t// Note that the precompile does not return zero but returns nothing.\n function f() public returns (address) {\n return ecrecover(bytes32(type(uint256).max), 1, bytes32(uint(2)), bytes32(uint(3)));\n }\n}\n// ----\n// f() -> 0\n" + }, + "failing_ecrecover_invalid_input_proper.sol": { + "content": "contract C {\n function f() public returns (address) {\n return recover(\n 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n 0, // invalid v value\n 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d,\n 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c,\n 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c\n );\n }\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt)\n public returns (address)\n {\n require(hash == keccak256(abi.encodePacked(blockExpired, salt)));\n return ecrecover(hash, v, r, s);\n }\n}\n// ----\n// f() -> 0\n" + }, + "ecrecover.sol": { + "content": "contract test {\n function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n return ecrecover(h, v, r, s);\n }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2.sol b/examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2.sol new file mode 100644 index 00000000..995a1e45 --- /dev/null +++ b/examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; +contract test { + function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) { + return ecrecover(h, v, r, s); + } +} +// ---- +// a(bytes32,uint8,bytes32,bytes32): +// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c, +// 28, +// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f, +// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549 +// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b diff --git a/examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2_standard_input.json b/examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2_standard_input.json new file mode 100644 index 00000000..a55196ff --- /dev/null +++ b/examples/test/semanticTests/ecrecover_ecrecover_abiV2/ecrecover_abiV2_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "ecrecover_abiV2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n return ecrecover(h, v, r, s);\n }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input.sol b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input.sol new file mode 100644 index 00000000..55621bdc --- /dev/null +++ b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input.sol @@ -0,0 +1,10 @@ +contract C { + // ecrecover should return zero for malformed input + // (v should be 27 or 28, not 1) + // Note that the precompile does not return zero but returns nothing. + function f() public returns (address) { + return ecrecover(bytes32(type(uint256).max), 1, bytes32(uint(2)), bytes32(uint(3))); + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input_standard_input.json b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input_standard_input.json new file mode 100644 index 00000000..a23c99a7 --- /dev/null +++ b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input/failing_ecrecover_invalid_input_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "ecrecover_abiV2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n return ecrecover(h, v, r, s);\n }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n" + }, + "failing_ecrecover_invalid_input_asm.sol": { + "content": "contract C {\n function f() public returns (address) {\n assembly {\n mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c)\n }\n return ecrecover(\n 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n 0, // invalid v value\n 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d\n );\n }\n}\n// ----\n// f() -> 0\n" + }, + "failing_ecrecover_invalid_input.sol": { + "content": "contract C {\n // ecrecover should return zero for malformed input\n\t// (v should be 27 or 28, not 1)\n\t// Note that the precompile does not return zero but returns nothing.\n function f() public returns (address) {\n return ecrecover(bytes32(type(uint256).max), 1, bytes32(uint(2)), bytes32(uint(3)));\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm.sol b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm.sol new file mode 100644 index 00000000..5e8c3cdb --- /dev/null +++ b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm.sol @@ -0,0 +1,15 @@ +contract C { + function f() public returns (address) { + assembly { + mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c) + } + return ecrecover( + 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca, + 0, // invalid v value + 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4, + 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d + ); + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm_standard_input.json b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm_standard_input.json new file mode 100644 index 00000000..717beed7 --- /dev/null +++ b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_asm/failing_ecrecover_invalid_input_asm_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "ecrecover_abiV2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n return ecrecover(h, v, r, s);\n }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n" + }, + "failing_ecrecover_invalid_input_asm.sol": { + "content": "contract C {\n function f() public returns (address) {\n assembly {\n mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c)\n }\n return ecrecover(\n 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n 0, // invalid v value\n 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d\n );\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper.sol b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper.sol new file mode 100644 index 00000000..511bd4e4 --- /dev/null +++ b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper.sol @@ -0,0 +1,20 @@ +contract C { + function f() public returns (address) { + return recover( + 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca, + 0, // invalid v value + 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4, + 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d, + 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c, + 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c + ); + } + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt) + public returns (address) + { + require(hash == keccak256(abi.encodePacked(blockExpired, salt))); + return ecrecover(hash, v, r, s); + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper_standard_input.json b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper_standard_input.json new file mode 100644 index 00000000..b62fcd42 --- /dev/null +++ b/examples/test/semanticTests/ecrecover_failing_ecrecover_invalid_input_proper/failing_ecrecover_invalid_input_proper_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "ecrecover_abiV2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {\n return ecrecover(h, v, r, s);\n }\n}\n// ----\n// a(bytes32,uint8,bytes32,bytes32):\n// 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c,\n// 28,\n// 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f,\n// 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549\n// -> 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\n" + }, + "failing_ecrecover_invalid_input_asm.sol": { + "content": "contract C {\n function f() public returns (address) {\n assembly {\n mstore(mload(0x40), 0xca35b7d915458ef540ade6068dfe2f44e8fa733c)\n }\n return ecrecover(\n 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n 0, // invalid v value\n 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d\n );\n }\n}\n// ----\n// f() -> 0\n" + }, + "failing_ecrecover_invalid_input.sol": { + "content": "contract C {\n // ecrecover should return zero for malformed input\n\t// (v should be 27 or 28, not 1)\n\t// Note that the precompile does not return zero but returns nothing.\n function f() public returns (address) {\n return ecrecover(bytes32(type(uint256).max), 1, bytes32(uint(2)), bytes32(uint(3)));\n }\n}\n// ----\n// f() -> 0\n" + }, + "failing_ecrecover_invalid_input_proper.sol": { + "content": "contract C {\n function f() public returns (address) {\n return recover(\n 0x77e5189111eb6557e8a637b27ef8fbb15bc61d61c2f00cc48878f3a296e5e0ca,\n 0, // invalid v value\n 0x6944c77849b18048f6abe0db8084b0d0d0689cdddb53d2671c36967b58691ad4,\n 0xef4f06ba4f78319baafd0424365777241af4dfd3da840471b4b4b087b7750d0d,\n 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c,\n 0x000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c\n );\n }\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s, uint blockExpired, bytes32 salt)\n public returns (address)\n {\n require(hash == keccak256(abi.encodePacked(blockExpired, salt)));\n return ecrecover(hash, v, r, s);\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events.sol b/examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events.sol new file mode 100644 index 00000000..dec367e1 --- /dev/null +++ b/examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events.sol @@ -0,0 +1,14 @@ +contract C { + event Terminated(); + + function terminate() external { + emit Terminated(); + emit Terminated(); + emit Terminated(); + } +} +// ---- +// terminate() -> +// ~ emit Terminated() +// ~ emit Terminated() +// ~ emit Terminated() \ No newline at end of file diff --git a/examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events_standard_input.json b/examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events_standard_input.json new file mode 100644 index 00000000..348bdc9e --- /dev/null +++ b/examples/test/semanticTests/emit_three_identical_events_1/emit_three_identical_events_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events.sol b/examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events.sol new file mode 100644 index 00000000..85cdceaf --- /dev/null +++ b/examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events.sol @@ -0,0 +1,12 @@ +contract C { + event Terminated(); + + function terminate() external { + emit Terminated(); + emit Terminated(); + } +} +// ---- +// terminate() -> +// ~ emit Terminated() +// ~ emit Terminated() \ No newline at end of file diff --git a/examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events_standard_input.json b/examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events_standard_input.json new file mode 100644 index 00000000..5bda75b3 --- /dev/null +++ b/examples/test/semanticTests/emit_two_identical_events_1/emit_two_identical_events_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/empty_contract_1/empty_contract.sol b/examples/test/semanticTests/empty_contract_1/empty_contract.sol new file mode 100644 index 00000000..7c1ae284 --- /dev/null +++ b/examples/test/semanticTests/empty_contract_1/empty_contract.sol @@ -0,0 +1,6 @@ +contract test { +} +// ==== +// allowNonExistingFunctions: true +// ---- +// i_am_not_there() -> FAILURE diff --git a/examples/test/semanticTests/empty_contract_1/empty_contract_standard_input.json b/examples/test/semanticTests/empty_contract_1/empty_contract_standard_input.json new file mode 100644 index 00000000..e86ac71d --- /dev/null +++ b/examples/test/semanticTests/empty_contract_1/empty_contract_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + }, + "c99_scoping_activation.sol": { + "content": "contract test {\n function f() pure public returns (uint) {\n uint x = 7;\n {\n x = 3; // This should still assign to the outer variable\n uint x;\n x = 4; // This should assign to the new one\n }\n return x;\n }\n function g() pure public returns (uint x) {\n x = 7;\n {\n x = 3;\n uint x;\n return x; // This returns the new variable, i.e. 0\n }\n }\n function h() pure public returns (uint x, uint a, uint b) {\n x = 7;\n {\n x = 3;\n a = x; // This should read from the outer\n uint x = 4;\n b = x;\n }\n }\n function i() pure public returns (uint x, uint a) {\n x = 7;\n {\n x = 3;\n uint x = x; // This should read from the outer and assign to the inner\n a = x;\n }\n }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n" + }, + "empty_contract.sol": { + "content": "contract test {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// i_am_not_there() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/empty_for_loop_1/empty_for_loop.sol b/examples/test/semanticTests/empty_for_loop_1/empty_for_loop.sol new file mode 100644 index 00000000..450134b6 --- /dev/null +++ b/examples/test/semanticTests/empty_for_loop_1/empty_for_loop.sol @@ -0,0 +1,11 @@ +contract test { + function f() public returns(uint ret) { + ret = 1; + for (;;) { + ret += 1; + if (ret >= 10) break; + } + } +} +// ---- +// f() -> 10 diff --git a/examples/test/semanticTests/empty_for_loop_1/empty_for_loop_standard_input.json b/examples/test/semanticTests/empty_for_loop_1/empty_for_loop_standard_input.json new file mode 100644 index 00000000..197ee8c8 --- /dev/null +++ b/examples/test/semanticTests/empty_for_loop_1/empty_for_loop_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints.sol b/examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints.sol new file mode 100644 index 00000000..beabc514 --- /dev/null +++ b/examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints.sol @@ -0,0 +1,9 @@ +contract c { + enum Truth {False, True} + + function test() public returns (uint256) { + return uint256(Truth(uint8(0x1))); + } +} +// ---- +// test() -> 1 diff --git a/examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints_standard_input.json b/examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints_standard_input.json new file mode 100644 index 00000000..e3cdbdee --- /dev/null +++ b/examples/test/semanticTests/enums_constructing_enums_from_ints/constructing_enums_from_ints_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow.sol b/examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow.sol new file mode 100644 index 00000000..b952524b --- /dev/null +++ b/examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow.sol @@ -0,0 +1,31 @@ +contract test { + enum ActionChoices {GoLeft, GoRight, GoStraight} + + constructor() {} + + function getChoiceExp(uint256 x) public returns (uint256 d) { + choice = ActionChoices(x); + d = uint256(choice); + } + + function getChoiceFromSigned(int256 x) public returns (uint256 d) { + choice = ActionChoices(x); + d = uint256(choice); + } + + function getChoiceFromMax() public returns (uint256 d) { + choice = ActionChoices(type(uint).max); + d = uint256(choice); + } + + ActionChoices choice; +} +// ==== +// EVMVersion: >=byzantium +// ---- +// getChoiceExp(uint256): 2 -> 2 +// getChoiceExp(uint256): 3 -> FAILURE, hex"4e487b71", 0x21 # These should throw # +// getChoiceFromSigned(int256): -1 -> FAILURE, hex"4e487b71", 0x21 +// getChoiceFromMax() -> FAILURE, hex"4e487b71", 0x21 +// getChoiceExp(uint256): 2 -> 2 # These should work # +// getChoiceExp(uint256): 0 -> 0 diff --git a/examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow_standard_input.json b/examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow_standard_input.json new file mode 100644 index 00000000..a4d3ca83 --- /dev/null +++ b/examples/test/semanticTests/enums_enum_explicit_overflow/enum_explicit_overflow_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead.sol b/examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead.sol new file mode 100644 index 00000000..60a1d64d --- /dev/null +++ b/examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead.sol @@ -0,0 +1,30 @@ +contract test { + enum ActionChoices {GoLeft, GoRight, GoStraight} + + constructor() {} + + function getChoiceExp(uint256 x) public returns (uint256 d) { + choice = ActionChoices(x); + d = uint256(choice); + } + + function getChoiceFromSigned(int256 x) public returns (uint256 d) { + choice = ActionChoices(x); + d = uint256(choice); + } + + function getChoiceFromMax() public returns (uint256 d) { + choice = ActionChoices(type(uint256).max); + d = uint256(choice); + } + + ActionChoices choice; +} +// ==== +// EVMVersion: FAILURE # These should throw # +// getChoiceFromSigned(int256): -1 -> FAILURE +// getChoiceFromMax() -> FAILURE +// getChoiceExp(uint256): 2 -> 2 # These should work # +// getChoiceExp(uint256): 0 -> 0 diff --git a/examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead_standard_input.json b/examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead_standard_input.json new file mode 100644 index 00000000..ae08d126 --- /dev/null +++ b/examples/test/semanticTests/enums_enum_explicit_overflow_homestead/enum_explicit_overflow_homestead_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_enum_referencing/enum_referencing.sol b/examples/test/semanticTests/enums_enum_referencing/enum_referencing.sol new file mode 100644 index 00000000..c58f6e83 --- /dev/null +++ b/examples/test/semanticTests/enums_enum_referencing/enum_referencing.sol @@ -0,0 +1,38 @@ +interface I { + enum Direction { A, B, Left, Right } +} +library L { + enum Direction { Left, Right } + function f() public pure returns (Direction) { + return Direction.Right; + } + function g() public pure returns (I.Direction) { + return I.Direction.Right; + } +} +contract C is I { + function f() public pure returns (Direction) { + return Direction.Right; + } + function g() public pure returns (I.Direction) { + return I.Direction.Right; + } + function h() public pure returns (L.Direction) { + return L.Direction.Right; + } + function x() public pure returns (L.Direction) { + return L.f(); + } + function y() public pure returns (I.Direction) { + return L.g(); + } +} +// ---- +// library: L +// f() -> 3 +// g() -> 3 +// f() -> 3 +// g() -> 3 +// h() -> 1 +// x() -> 1 +// y() -> 3 diff --git a/examples/test/semanticTests/enums_enum_referencing/enum_referencing_standard_input.json b/examples/test/semanticTests/enums_enum_referencing/enum_referencing_standard_input.json new file mode 100644 index 00000000..5fc04ce1 --- /dev/null +++ b/examples/test/semanticTests/enums_enum_referencing/enum_referencing_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members.sol b/examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members.sol new file mode 100644 index 00000000..8bfded3c --- /dev/null +++ b/examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members.sol @@ -0,0 +1,58 @@ +pragma abicoder v2; +enum E { + E000, E001, E002, E003, E004, E005, E006, E007, E008, E009, + E010, E011, E012, E013, E014, E015, E016, E017, E018, E019, + E020, E021, E022, E023, E024, E025, E026, E027, E028, E029, + E030, E031, E032, E033, E034, E035, E036, E037, E038, E039, + E040, E041, E042, E043, E044, E045, E046, E047, E048, E049, + E050, E051, E052, E053, E054, E055, E056, E057, E058, E059, + E060, E061, E062, E063, E064, E065, E066, E067, E068, E069, + E070, E071, E072, E073, E074, E075, E076, E077, E078, E079, + E080, E081, E082, E083, E084, E085, E086, E087, E088, E089, + E090, E091, E092, E093, E094, E095, E096, E097, E098, E099, + E100, E101, E102, E103, E104, E105, E106, E107, E108, E109, + E110, E111, E112, E113, E114, E115, E116, E117, E118, E119, + E120, E121, E122, E123, E124, E125, E126, E127, E128, E129, + E130, E131, E132, E133, E134, E135, E136, E137, E138, E139, + E140, E141, E142, E143, E144, E145, E146, E147, E148, E149, + E150, E151, E152, E153, E154, E155, E156, E157, E158, E159, + E160, E161, E162, E163, E164, E165, E166, E167, E168, E169, + E170, E171, E172, E173, E174, E175, E176, E177, E178, E179, + E180, E181, E182, E183, E184, E185, E186, E187, E188, E189, + E190, E191, E192, E193, E194, E195, E196, E197, E198, E199, + E200, E201, E202, E203, E204, E205, E206, E207, E208, E209, + E210, E211, E212, E213, E214, E215, E216, E217, E218, E219, + E220, E221, E222, E223, E224, E225, E226, E227, E228, E229, + E230, E231, E232, E233, E234, E235, E236, E237, E238, E239, + E240, E241, E242, E243, E244, E245, E246, E247, E248, E249, + E250, E251, E252, E253, E254, E255 +} + +contract C { + function getMinMax() public returns (E, E) { + return (E.E000, E.E255); + } + + function intToEnum(uint8 _i) public returns (E) { + return E(_i); + } + + function enumToInt(E _e) public returns (uint8) { + return uint8(_e); + } + + function decodeEnum(bytes memory data) public returns (E) { + (E e) = abi.decode(data, (E)); + return e; + } +} +// ---- +// getMinMax() -> 0, 255 +// intToEnum(uint8): 0 -> 0 +// intToEnum(uint8): 255 -> 255 +// enumToInt(uint8): 0 -> 0 +// enumToInt(uint8): 255 -> 255 +// enumToInt(uint8): 256 -> FAILURE +// decodeEnum(bytes): 0x20, 32, 0 -> 0 +// decodeEnum(bytes): 0x20, 32, 255 -> 255 +// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE diff --git a/examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members_standard_input.json b/examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members_standard_input.json new file mode 100644 index 00000000..fce607ae --- /dev/null +++ b/examples/test/semanticTests/enums_enum_with_256_members/enum_with_256_members_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + }, + "enum_with_256_members.sol": { + "content": "pragma abicoder v2;\nenum E {\n E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n function getMinMax() public returns (E, E) {\n return (E.E000, E.E255);\n }\n\n function intToEnum(uint8 _i) public returns (E) {\n return E(_i);\n }\n\n function enumToInt(E _e) public returns (uint8) {\n return uint8(_e);\n }\n\n function decodeEnum(bytes memory data) public returns (E) {\n (E e) = abi.decode(data, (E));\n return e;\n }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged.sol b/examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged.sol new file mode 100644 index 00000000..243a7920 --- /dev/null +++ b/examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged.sol @@ -0,0 +1,22 @@ +contract C { + enum X { A, B } + event Log(X); + + function test_log() public returns (uint) { + X garbled = X.A; + assembly { + garbled := 5 + } + emit Log(garbled); + return 1; + } + function test_log_ok() public returns (uint) { + X x = X.A; + emit Log(x); + return 1; + } +} +// ---- +// test_log_ok() -> 1 +// ~ emit Log(uint8): 0x00 +// test_log() -> FAILURE, hex"4e487b71", 0x21 diff --git a/examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged_standard_input.json b/examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged_standard_input.json new file mode 100644 index 00000000..442a7e8c --- /dev/null +++ b/examples/test/semanticTests/enums_invalid_enum_logged/invalid_enum_logged_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_minmax/minmax.sol b/examples/test/semanticTests/enums_minmax/minmax.sol new file mode 100644 index 00000000..a447f643 --- /dev/null +++ b/examples/test/semanticTests/enums_minmax/minmax.sol @@ -0,0 +1,9 @@ +contract test { + enum MinMax { A, B, C, D } + + function min() public returns(uint) { return uint(type(MinMax).min); } + function max() public returns(uint) { return uint(type(MinMax).max); } +} +// ---- +// min() -> 0 +// max() -> 3 diff --git a/examples/test/semanticTests/enums_minmax/minmax_standard_input.json b/examples/test/semanticTests/enums_minmax/minmax_standard_input.json new file mode 100644 index 00000000..e8463a47 --- /dev/null +++ b/examples/test/semanticTests/enums_minmax/minmax_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + }, + "enum_with_256_members.sol": { + "content": "pragma abicoder v2;\nenum E {\n E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n function getMinMax() public returns (E, E) {\n return (E.E000, E.E255);\n }\n\n function intToEnum(uint8 _i) public returns (E) {\n return E(_i);\n }\n\n function enumToInt(E _e) public returns (uint8) {\n return uint8(_e);\n }\n\n function decodeEnum(bytes memory data) public returns (E) {\n (E e) = abi.decode(data, (E));\n return e;\n }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n" + }, + "using_contract_enums_with_explicit_contract_name.sol": { + "content": "contract test {\n enum Choice {A, B, C}\n\n function answer() public returns (test.Choice _ret) {\n _ret = test.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_inherited_enum_excplicitly.sol": { + "content": "contract base {\n enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n function answer() public returns (base.Choice _ret) {\n _ret = base.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_enums.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n\n constructor() {\n choices = ActionChoices.GoStraight;\n }\n\n function getChoice() public returns (uint256 d) {\n d = uint256(choices);\n }\n\n ActionChoices choices;\n}\n// ----\n// getChoice() -> 2\n" + }, + "using_inherited_enum.sol": { + "content": "contract base {\n enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n function answer() public returns (Choice _ret) {\n _ret = Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "minmax.sol": { + "content": "contract test {\n\tenum MinMax { A, B, C, D }\n\n\tfunction min() public returns(uint) { return uint(type(MinMax).min); }\n\tfunction max() public returns(uint) { return uint(type(MinMax).max); }\n}\n// ----\n// min() -> 0\n// max() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name.sol b/examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name.sol new file mode 100644 index 00000000..a3bce93a --- /dev/null +++ b/examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name.sol @@ -0,0 +1,9 @@ +contract test { + enum Choice {A, B, C} + + function answer() public returns (test.Choice _ret) { + _ret = test.Choice.B; + } +} +// ---- +// answer() -> 1 diff --git a/examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name_standard_input.json b/examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name_standard_input.json new file mode 100644 index 00000000..3f10acd3 --- /dev/null +++ b/examples/test/semanticTests/enums_using_contract_enums_with_explicit_contract_name/using_contract_enums_with_explicit_contract_name_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + }, + "enum_with_256_members.sol": { + "content": "pragma abicoder v2;\nenum E {\n E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n function getMinMax() public returns (E, E) {\n return (E.E000, E.E255);\n }\n\n function intToEnum(uint8 _i) public returns (E) {\n return E(_i);\n }\n\n function enumToInt(E _e) public returns (uint8) {\n return uint8(_e);\n }\n\n function decodeEnum(bytes memory data) public returns (E) {\n (E e) = abi.decode(data, (E));\n return e;\n }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n" + }, + "using_contract_enums_with_explicit_contract_name.sol": { + "content": "contract test {\n enum Choice {A, B, C}\n\n function answer() public returns (test.Choice _ret) {\n _ret = test.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_using_enums/using_enums.sol b/examples/test/semanticTests/enums_using_enums/using_enums.sol new file mode 100644 index 00000000..b4d0ce8e --- /dev/null +++ b/examples/test/semanticTests/enums_using_enums/using_enums.sol @@ -0,0 +1,15 @@ +contract test { + enum ActionChoices {GoLeft, GoRight, GoStraight, Sit} + + constructor() { + choices = ActionChoices.GoStraight; + } + + function getChoice() public returns (uint256 d) { + d = uint256(choices); + } + + ActionChoices choices; +} +// ---- +// getChoice() -> 2 diff --git a/examples/test/semanticTests/enums_using_enums/using_enums_standard_input.json b/examples/test/semanticTests/enums_using_enums/using_enums_standard_input.json new file mode 100644 index 00000000..8303b84e --- /dev/null +++ b/examples/test/semanticTests/enums_using_enums/using_enums_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + }, + "enum_with_256_members.sol": { + "content": "pragma abicoder v2;\nenum E {\n E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n function getMinMax() public returns (E, E) {\n return (E.E000, E.E255);\n }\n\n function intToEnum(uint8 _i) public returns (E) {\n return E(_i);\n }\n\n function enumToInt(E _e) public returns (uint8) {\n return uint8(_e);\n }\n\n function decodeEnum(bytes memory data) public returns (E) {\n (E e) = abi.decode(data, (E));\n return e;\n }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n" + }, + "using_contract_enums_with_explicit_contract_name.sol": { + "content": "contract test {\n enum Choice {A, B, C}\n\n function answer() public returns (test.Choice _ret) {\n _ret = test.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_inherited_enum_excplicitly.sol": { + "content": "contract base {\n enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n function answer() public returns (base.Choice _ret) {\n _ret = base.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_enums.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n\n constructor() {\n choices = ActionChoices.GoStraight;\n }\n\n function getChoice() public returns (uint256 d) {\n d = uint256(choices);\n }\n\n ActionChoices choices;\n}\n// ----\n// getChoice() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum.sol b/examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum.sol new file mode 100644 index 00000000..9741568b --- /dev/null +++ b/examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum.sol @@ -0,0 +1,12 @@ +contract base { + enum Choice {A, B, C} +} + + +contract test is base { + function answer() public returns (Choice _ret) { + _ret = Choice.B; + } +} +// ---- +// answer() -> 1 diff --git a/examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum_standard_input.json b/examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum_standard_input.json new file mode 100644 index 00000000..ca82c650 --- /dev/null +++ b/examples/test/semanticTests/enums_using_inherited_enum/using_inherited_enum_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + }, + "enum_with_256_members.sol": { + "content": "pragma abicoder v2;\nenum E {\n E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n function getMinMax() public returns (E, E) {\n return (E.E000, E.E255);\n }\n\n function intToEnum(uint8 _i) public returns (E) {\n return E(_i);\n }\n\n function enumToInt(E _e) public returns (uint8) {\n return uint8(_e);\n }\n\n function decodeEnum(bytes memory data) public returns (E) {\n (E e) = abi.decode(data, (E));\n return e;\n }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n" + }, + "using_contract_enums_with_explicit_contract_name.sol": { + "content": "contract test {\n enum Choice {A, B, C}\n\n function answer() public returns (test.Choice _ret) {\n _ret = test.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_inherited_enum_excplicitly.sol": { + "content": "contract base {\n enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n function answer() public returns (base.Choice _ret) {\n _ret = base.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_enums.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight, Sit}\n\n constructor() {\n choices = ActionChoices.GoStraight;\n }\n\n function getChoice() public returns (uint256 d) {\n d = uint256(choices);\n }\n\n ActionChoices choices;\n}\n// ----\n// getChoice() -> 2\n" + }, + "using_inherited_enum.sol": { + "content": "contract base {\n enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n function answer() public returns (Choice _ret) {\n _ret = Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly.sol b/examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly.sol new file mode 100644 index 00000000..eb1d63a2 --- /dev/null +++ b/examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly.sol @@ -0,0 +1,12 @@ +contract base { + enum Choice {A, B, C} +} + + +contract test is base { + function answer() public returns (base.Choice _ret) { + _ret = base.Choice.B; + } +} +// ---- +// answer() -> 1 diff --git a/examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly_standard_input.json b/examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly_standard_input.json new file mode 100644 index 00000000..bfa44e8f --- /dev/null +++ b/examples/test/semanticTests/enums_using_inherited_enum_excplicitly/using_inherited_enum_excplicitly_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "enum_explicit_overflow_homestead.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint256).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: FAILURE # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE\n// getChoiceFromMax() -> FAILURE\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "constructing_enums_from_ints.sol": { + "content": "contract c {\n enum Truth {False, True}\n\n function test() public returns (uint256) {\n return uint256(Truth(uint8(0x1)));\n }\n}\n// ----\n// test() -> 1\n" + }, + "enum_explicit_overflow.sol": { + "content": "contract test {\n enum ActionChoices {GoLeft, GoRight, GoStraight}\n\n constructor() {}\n\n function getChoiceExp(uint256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromSigned(int256 x) public returns (uint256 d) {\n choice = ActionChoices(x);\n d = uint256(choice);\n }\n\n function getChoiceFromMax() public returns (uint256 d) {\n choice = ActionChoices(type(uint).max);\n d = uint256(choice);\n }\n\n ActionChoices choice;\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// getChoiceExp(uint256): 2 -> 2\n// getChoiceExp(uint256): 3 -> FAILURE, hex\"4e487b71\", 0x21 # These should throw #\n// getChoiceFromSigned(int256): -1 -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceFromMax() -> FAILURE, hex\"4e487b71\", 0x21\n// getChoiceExp(uint256): 2 -> 2 # These should work #\n// getChoiceExp(uint256): 0 -> 0\n" + }, + "invalid_enum_logged.sol": { + "content": "contract C {\n enum X { A, B }\n event Log(X);\n\n function test_log() public returns (uint) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n emit Log(garbled);\n return 1;\n }\n function test_log_ok() public returns (uint) {\n X x = X.A;\n emit Log(x);\n return 1;\n }\n}\n// ----\n// test_log_ok() -> 1\n// ~ emit Log(uint8): 0x00\n// test_log() -> FAILURE, hex\"4e487b71\", 0x21\n" + }, + "enum_referencing.sol": { + "content": "interface I {\n enum Direction { A, B, Left, Right }\n}\nlibrary L {\n enum Direction { Left, Right }\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n}\ncontract C is I {\n function f() public pure returns (Direction) {\n return Direction.Right;\n }\n function g() public pure returns (I.Direction) {\n return I.Direction.Right;\n }\n function h() public pure returns (L.Direction) {\n return L.Direction.Right;\n }\n function x() public pure returns (L.Direction) {\n return L.f();\n }\n function y() public pure returns (I.Direction) {\n return L.g();\n }\n}\n// ----\n// library: L\n// f() -> 3\n// g() -> 3\n// f() -> 3\n// g() -> 3\n// h() -> 1\n// x() -> 1\n// y() -> 3\n" + }, + "enum_with_256_members.sol": { + "content": "pragma abicoder v2;\nenum E {\n E000, E001, E002, E003, E004, E005, E006, E007, E008, E009,\n E010, E011, E012, E013, E014, E015, E016, E017, E018, E019,\n E020, E021, E022, E023, E024, E025, E026, E027, E028, E029,\n E030, E031, E032, E033, E034, E035, E036, E037, E038, E039,\n E040, E041, E042, E043, E044, E045, E046, E047, E048, E049,\n E050, E051, E052, E053, E054, E055, E056, E057, E058, E059,\n E060, E061, E062, E063, E064, E065, E066, E067, E068, E069,\n E070, E071, E072, E073, E074, E075, E076, E077, E078, E079,\n E080, E081, E082, E083, E084, E085, E086, E087, E088, E089,\n E090, E091, E092, E093, E094, E095, E096, E097, E098, E099,\n E100, E101, E102, E103, E104, E105, E106, E107, E108, E109,\n E110, E111, E112, E113, E114, E115, E116, E117, E118, E119,\n E120, E121, E122, E123, E124, E125, E126, E127, E128, E129,\n E130, E131, E132, E133, E134, E135, E136, E137, E138, E139,\n E140, E141, E142, E143, E144, E145, E146, E147, E148, E149,\n E150, E151, E152, E153, E154, E155, E156, E157, E158, E159,\n E160, E161, E162, E163, E164, E165, E166, E167, E168, E169,\n E170, E171, E172, E173, E174, E175, E176, E177, E178, E179,\n E180, E181, E182, E183, E184, E185, E186, E187, E188, E189,\n E190, E191, E192, E193, E194, E195, E196, E197, E198, E199,\n E200, E201, E202, E203, E204, E205, E206, E207, E208, E209,\n E210, E211, E212, E213, E214, E215, E216, E217, E218, E219,\n E220, E221, E222, E223, E224, E225, E226, E227, E228, E229,\n E230, E231, E232, E233, E234, E235, E236, E237, E238, E239,\n E240, E241, E242, E243, E244, E245, E246, E247, E248, E249,\n E250, E251, E252, E253, E254, E255\n}\n\ncontract C {\n function getMinMax() public returns (E, E) {\n return (E.E000, E.E255);\n }\n\n function intToEnum(uint8 _i) public returns (E) {\n return E(_i);\n }\n\n function enumToInt(E _e) public returns (uint8) {\n return uint8(_e);\n }\n\n function decodeEnum(bytes memory data) public returns (E) {\n (E e) = abi.decode(data, (E));\n return e;\n }\n}\n// ----\n// getMinMax() -> 0, 255\n// intToEnum(uint8): 0 -> 0\n// intToEnum(uint8): 255 -> 255\n// enumToInt(uint8): 0 -> 0\n// enumToInt(uint8): 255 -> 255\n// enumToInt(uint8): 256 -> FAILURE\n// decodeEnum(bytes): 0x20, 32, 0 -> 0\n// decodeEnum(bytes): 0x20, 32, 255 -> 255\n// decodeEnum(bytes): 0x20, 32, 256 -> FAILURE\n" + }, + "using_contract_enums_with_explicit_contract_name.sol": { + "content": "contract test {\n enum Choice {A, B, C}\n\n function answer() public returns (test.Choice _ret) {\n _ret = test.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + }, + "using_inherited_enum_excplicitly.sol": { + "content": "contract base {\n enum Choice {A, B, C}\n}\n\n\ncontract test is base {\n function answer() public returns (base.Choice _ret) {\n _ret = base.Choice.B;\n }\n}\n// ----\n// answer() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface.sol b/examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface.sol new file mode 100644 index 00000000..fad9d8bb --- /dev/null +++ b/examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface.sol @@ -0,0 +1,22 @@ +error E(uint a); +library L { + error E(uint a, uint b); +} +interface I { + error E(uint a, uint b, uint c); +} +contract C { + function f() public pure { + revert E(1); + } + function g() public pure { + revert L.E(1, 2); + } + function h() public pure { + revert I.E(1, 2, 3); + } +} +// ---- +// f() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000001" +// g() -> FAILURE, hex"85208890", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000002" +// h() -> FAILURE, hex"7924ea7c", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000003" diff --git a/examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface_standard_input.json b/examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface_standard_input.json new file mode 100644 index 00000000..137c52c9 --- /dev/null +++ b/examples/test/semanticTests/errors_error_in_library_and_interface/error_in_library_and_interface_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_error_selector/error_selector.sol b/examples/test/semanticTests/errors_error_selector/error_selector.sol new file mode 100644 index 00000000..e7e40fd6 --- /dev/null +++ b/examples/test/semanticTests/errors_error_selector/error_selector.sol @@ -0,0 +1,48 @@ +library L { + error E(); +} +library S { + error E(uint); +} +library T { + error E(); +} + +error E(); + +interface I { + error E(); + function f() external pure; +} + +contract D { + error F(); +} + +contract C is D { + function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) { + assert(L.E.selector == T.E.selector); + assert(L.E.selector != S.E.selector); + assert(E.selector == L.E.selector); + assert(I.E.selector == L.E.selector); + return (L.E.selector, S.E.selector, E.selector, I.E.selector); + } + + bytes4 s1 = L.E.selector; + bytes4 s2 = S.E.selector; + bytes4 s3 = T.E.selector; + bytes4 s4 = I.E.selector; + function test2() external returns (bytes4, bytes4, bytes4, bytes4) { + return (s1, s2, s3, s4); + } + + function test3() external returns (bytes4) { + return (F.selector); + } +} +// ==== +// compileViaYul: also +// ---- +// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000 +// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000 +// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/errors_error_selector/error_selector_standard_input.json b/examples/test/semanticTests/errors_error_selector/error_selector_standard_input.json new file mode 100644 index 00000000..4d9bec45 --- /dev/null +++ b/examples/test/semanticTests/errors_error_selector/error_selector_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array.sol b/examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array.sol new file mode 100644 index 00000000..bfda3b12 --- /dev/null +++ b/examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array.sol @@ -0,0 +1,10 @@ +contract C { + error E(uint[], uint[1]); + + // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug. + function f(uint[] memory a, uint[1] calldata b) public { + revert E(a, b); + } +} +// ---- +// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex"f42f106d", 0x40, 0xff, 1, 0xffff diff --git a/examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array_standard_input.json b/examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array_standard_input.json new file mode 100644 index 00000000..04738b7a --- /dev/null +++ b/examples/test/semanticTests/errors_error_static_calldata_uint_array_and_dynamic_array/error_static_calldata_uint_array_and_dynamic_array_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type.sol b/examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type.sol new file mode 100644 index 00000000..bc70b5be --- /dev/null +++ b/examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type.sol @@ -0,0 +1,45 @@ +pragma abicoder v2; + +struct S { + uint256 a; + bool b; + string s; +} + +error E(); +error E1(uint256); +error E2(string); +error E3(S); +error E4(address); +error E5(function() external pure); + +contract C { + function a() external pure { + require(false, E()); + } + function b() external pure { + require(false, E1(1)); + } + function c() external pure { + require(false, E2("string literal")); + } + function d() external pure { + require(false, E3(S(1, true, "string literal"))); + } + function e() external view { + require(false, E4(address(this))); + } + function f() external view { + require(false, E5(this.a)); + } +} + +// ==== +// compileViaYul: true +// ---- +// a() -> FAILURE, hex"92bbf6e8" +// b() -> FAILURE, hex"47e26897", hex"0000000000000000000000000000000000000000000000000000000000000001" +// c() -> FAILURE, hex"8f372c34", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" +// d() -> FAILURE, hex"5717173e", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"000000000000000000000000000000000000000000000000000000000000000e", hex"737472696e67206c69746572616c000000000000000000000000000000000000" +// e() -> FAILURE, hex"7efef9ea", hex"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e" +// f() -> FAILURE, hex"0c3f12eb", hex"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000" diff --git a/examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type_standard_input.json b/examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type_standard_input.json new file mode 100644 index 00000000..ccc9be96 --- /dev/null +++ b/examples/test/semanticTests/errors_errors_by_parameter_type/errors_by_parameter_type_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_named_error_args/named_error_args.sol b/examples/test/semanticTests/errors_named_error_args/named_error_args.sol new file mode 100644 index 00000000..04697f52 --- /dev/null +++ b/examples/test/semanticTests/errors_named_error_args/named_error_args.sol @@ -0,0 +1,8 @@ +error E(uint a, uint b); +contract C { + function f() public pure { + revert E({b: 7, a: 2}); + } +} +// ---- +// f() -> FAILURE, hex"85208890", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000007" diff --git a/examples/test/semanticTests/errors_named_error_args/named_error_args_standard_input.json b/examples/test/semanticTests/errors_named_error_args/named_error_args_standard_input.json new file mode 100644 index 00000000..1c5f3a03 --- /dev/null +++ b/examples/test/semanticTests/errors_named_error_args/named_error_args_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + }, + "require_error_evaluation_order_2.sol": { + "content": "contract C {\n uint y;\n function g(bool x) internal returns (bool) {\n y = 42;\n return x;\n }\n error E(uint256);\n function h() internal returns (uint256) { return y; }\n function f(bool c) public {\n require(g(c), E(h()));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n" + }, + "weird_name.sol": { + "content": "error error(uint a);\ncontract C {\n function f() public pure {\n revert error(2);\n }\n}\n// ----\n// f() -> FAILURE, hex\"b48fb6cf\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n" + }, + "require_error_evaluation_order_1.sol": { + "content": "contract C\n{\n error E(uint);\n\n function r() internal returns (uint)\n {\n assembly { mstore(0, 7) return (0, 32) }\n return 42;\n }\n\n function f() public returns (uint)\n {\n require(false, E(r()));\n return 42;\n }\n\n function g() public returns (uint)\n {\n require(true, E(r()));\n return 42;\n }\n}\n\n// ----\n// f() -> 7\n// g() -> 7\n" + }, + "require_error_function_join_control_flow.sol": { + "content": "contract C {\n uint x = 0;\n uint y = 42;\n error E(uint);\n function f(bool c) public returns (uint256, uint256, uint256) {\n uint z = x;\n if (y == 42) {\n x = 21;\n } else {\n require(c, E(y));\n }\n y /= 2;\n return (x,y,z);\n }\n}\n// ----\n// f(bool): true -> 0x15, 0x15, 0\n// f(bool): false -> FAILURE, hex\"002ff067\", 21\n" + }, + "via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport \"s1.sol\" as S;\n==== Source: s3.sol ====\nimport \"s1.sol\" as S;\nimport \"s2.sol\" as T;\nimport \"s1.sol\";\ncontract C {\n function x() public pure {\n revert E(1);\n }\n function y() public pure {\n revert S.E(2);\n }\n function z() public pure {\n revert T.S.E(3);\n }\n}\n// ----\n// x() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// y() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// z() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "named_error_args.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E({b: 7, a: 2});\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000007\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types.sol b/examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types.sol new file mode 100644 index 00000000..2f2b7c67 --- /dev/null +++ b/examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + +contract C { + enum EnumType {A, B, C} + + struct StructType { + uint x; + } + + error E1(StructType StructType); + error E2(EnumType StructType, StructType EnumType); + + function f() public { + revert E1({StructType: StructType(42)}); + } + + function g() public { + revert E2({EnumType: StructType(42), StructType: EnumType.B}); + } +} +// ---- +// f() -> FAILURE, hex"33a54193", hex"000000000000000000000000000000000000000000000000000000000000002a" +// g() -> FAILURE, hex"374b9387", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"000000000000000000000000000000000000000000000000000000000000002a" diff --git a/examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types_standard_input.json b/examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types_standard_input.json new file mode 100644 index 00000000..11cd8198 --- /dev/null +++ b/examples/test/semanticTests/errors_named_parameters_shadowing_types/named_parameters_shadowing_types_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_panic_via_import/panic_via_import.sol b/examples/test/semanticTests/errors_panic_via_import/panic_via_import.sol new file mode 100644 index 00000000..94a6a7aa --- /dev/null +++ b/examples/test/semanticTests/errors_panic_via_import/panic_via_import.sol @@ -0,0 +1,16 @@ +==== Source: s1.sol ==== +error E(uint); +==== Source: s2.sol ==== +import { E as Panic } from "s1.sol"; +contract C { + error E(uint); + function a() public pure { + revert Panic(1); + } + function b() public pure { + revert E(1); + } +} +// ---- +// a() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000001" +// b() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000001" diff --git a/examples/test/semanticTests/errors_panic_via_import/panic_via_import_standard_input.json b/examples/test/semanticTests/errors_panic_via_import/panic_via_import_standard_input.json new file mode 100644 index 00000000..c78a2c9c --- /dev/null +++ b/examples/test/semanticTests/errors_panic_via_import/panic_via_import_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters.sol b/examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters.sol new file mode 100644 index 00000000..957cb0bb --- /dev/null +++ b/examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters.sol @@ -0,0 +1,19 @@ +error AnError(uint256, string, uint256); +error AnotherError(uint256, string, uint256); + +contract C +{ + function f() external pure + { + require(false, AnError(1, "two", 3)); + } + + function g() external pure + { + require(false, AnotherError(4, "five", 6)); + } +} + +// ---- +// f() -> FAILURE, hex"f55fefe3", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"44a06798", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000006", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"6669766500000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters_standard_input.json b/examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters_standard_input.json new file mode 100644 index 00000000..4a59838e --- /dev/null +++ b/examples/test/semanticTests/errors_require_different_errors_same_parameters/require_different_errors_same_parameters_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once.sol b/examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once.sol new file mode 100644 index 00000000..e344af43 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once.sol @@ -0,0 +1,24 @@ +contract C { + uint256 counter = 0; + + error CustomError(uint256); + + function getCounter() public view returns (uint256) { + return counter; + } + + function g(bool condition) internal returns (bool) { + counter++; + return condition; + } + + function f(bool condition) external { + require(g(condition), CustomError(counter)); + } +} + +// ---- +// f(bool): false -> FAILURE, hex"110b3655", 1 +// getCounter() -> 0 +// f(bool): true -> +// getCounter() -> 1 diff --git a/examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once_standard_input.json b/examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once_standard_input.json new file mode 100644 index 00000000..db9986b2 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_condition_evaluated_only_once/require_error_condition_evaluated_only_once_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1.sol b/examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1.sol new file mode 100644 index 00000000..019c282c --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1.sol @@ -0,0 +1,26 @@ +contract C +{ + error E(uint); + + function r() internal returns (uint) + { + assembly { mstore(0, 7) return (0, 32) } + return 42; + } + + function f() public returns (uint) + { + require(false, E(r())); + return 42; + } + + function g() public returns (uint) + { + require(true, E(r())); + return 42; + } +} + +// ---- +// f() -> 7 +// g() -> 7 diff --git a/examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1_standard_input.json b/examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1_standard_input.json new file mode 100644 index 00000000..9b06ff8e --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_evaluation_order_1/require_error_evaluation_order_1_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + }, + "require_error_evaluation_order_2.sol": { + "content": "contract C {\n uint y;\n function g(bool x) internal returns (bool) {\n y = 42;\n return x;\n }\n error E(uint256);\n function h() internal returns (uint256) { return y; }\n function f(bool c) public {\n require(g(c), E(h()));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n" + }, + "weird_name.sol": { + "content": "error error(uint a);\ncontract C {\n function f() public pure {\n revert error(2);\n }\n}\n// ----\n// f() -> FAILURE, hex\"b48fb6cf\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n" + }, + "require_error_evaluation_order_1.sol": { + "content": "contract C\n{\n error E(uint);\n\n function r() internal returns (uint)\n {\n assembly { mstore(0, 7) return (0, 32) }\n return 42;\n }\n\n function f() public returns (uint)\n {\n require(false, E(r()));\n return 42;\n }\n\n function g() public returns (uint)\n {\n require(true, E(r()));\n return 42;\n }\n}\n\n// ----\n// f() -> 7\n// g() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2.sol b/examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2.sol new file mode 100644 index 00000000..610caeef --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2.sol @@ -0,0 +1,16 @@ +contract C { + uint y; + function g(bool x) internal returns (bool) { + y = 42; + return x; + } + error E(uint256); + function h() internal returns (uint256) { return y; } + function f(bool c) public { + require(g(c), E(h())); + } +} + +// ---- +// f(bool): false -> FAILURE, hex"002ff067", 42 +// f(bool): true -> diff --git a/examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2_standard_input.json b/examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2_standard_input.json new file mode 100644 index 00000000..e901519a --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_evaluation_order_2/require_error_evaluation_order_2_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + }, + "require_error_evaluation_order_2.sol": { + "content": "contract C {\n uint y;\n function g(bool x) internal returns (bool) {\n y = 42;\n return x;\n }\n error E(uint256);\n function h() internal returns (uint256) { return y; }\n function f(bool c) public {\n require(g(c), E(h()));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3.sol b/examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3.sol new file mode 100644 index 00000000..0d70b16b --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3.sol @@ -0,0 +1,15 @@ +contract C { + string failureMessage = "Failure Message"; + function g(bool x) internal returns (bool) { + failureMessage = "Intercepted failure message"; + return x; + } + function h() internal returns (string memory) { return failureMessage; } + function f(bool c) public { + require(g(c), h()); + } +} + +// ---- +// f(bool): false -> FAILURE, hex"08c379a0", 0x20, 0x1b, "Intercepted failure message" +// f(bool): true -> diff --git a/examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3_standard_input.json b/examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3_standard_input.json new file mode 100644 index 00000000..36291344 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_evaluation_order_3/require_error_evaluation_order_3_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow.sol b/examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow.sol new file mode 100644 index 00000000..e3d7e5fd --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow.sol @@ -0,0 +1,18 @@ +contract C { + uint x = 0; + uint y = 42; + error E(uint); + function f(bool c) public returns (uint256, uint256, uint256) { + uint z = x; + if (y == 42) { + x = 21; + } else { + require(c, E(y)); + } + y /= 2; + return (x,y,z); + } +} +// ---- +// f(bool): true -> 0x15, 0x15, 0 +// f(bool): false -> FAILURE, hex"002ff067", 21 diff --git a/examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow_standard_input.json b/examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow_standard_input.json new file mode 100644 index 00000000..389e364f --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_function_join_control_flow/require_error_function_join_control_flow_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + }, + "require_error_evaluation_order_2.sol": { + "content": "contract C {\n uint y;\n function g(bool x) internal returns (bool) {\n y = 42;\n return x;\n }\n error E(uint256);\n function h() internal returns (uint256) { return y; }\n function f(bool c) public {\n require(g(c), E(h()));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n" + }, + "weird_name.sol": { + "content": "error error(uint a);\ncontract C {\n function f() public pure {\n revert error(2);\n }\n}\n// ----\n// f() -> FAILURE, hex\"b48fb6cf\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n" + }, + "require_error_evaluation_order_1.sol": { + "content": "contract C\n{\n error E(uint);\n\n function r() internal returns (uint)\n {\n assembly { mstore(0, 7) return (0, 32) }\n return 42;\n }\n\n function f() public returns (uint)\n {\n require(false, E(r()));\n return 42;\n }\n\n function g() public returns (uint)\n {\n require(true, E(r()));\n return 42;\n }\n}\n\n// ----\n// f() -> 7\n// g() -> 7\n" + }, + "require_error_function_join_control_flow.sol": { + "content": "contract C {\n uint x = 0;\n uint y = 42;\n error E(uint);\n function f(bool c) public returns (uint256, uint256, uint256) {\n uint z = x;\n if (y == 42) {\n x = 21;\n } else {\n require(c, E(y));\n }\n y /= 2;\n return (x,y,z);\n }\n}\n// ----\n// f(bool): true -> 0x15, 0x15, 0\n// f(bool): false -> FAILURE, hex\"002ff067\", 21\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter.sol b/examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter.sol new file mode 100644 index 00000000..3af19ca6 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter.sol @@ -0,0 +1,18 @@ +error CustomError(function(uint256) external pure returns (uint256)); + +contract C +{ + function e(uint256 x) external pure returns (uint256) + { + return x; + } + + function f() external view + { + // more than one stack slot + require(false, CustomError(this.e)); + } +} + +// ---- +// f() -> FAILURE, hex"271b1dfa", hex"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000" diff --git a/examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter_standard_input.json b/examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter_standard_input.json new file mode 100644 index 00000000..790c374a --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_function_pointer_parameter/require_error_function_pointer_parameter_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments.sol b/examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments.sol new file mode 100644 index 00000000..98254cf0 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments.sol @@ -0,0 +1,18 @@ +error CustomError(uint256, string, uint256); + +contract C +{ + function f() external pure + { + require(false, CustomError(1, "two", 3)); + } + + function g() external pure + { + require(false, CustomError(4, "five", 6)); + } +} + +// ---- +// f() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000006", hex"0000000000000000000000000000000000000000000000000000000000000004", hex"6669766500000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments_standard_input.json b/examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments_standard_input.json new file mode 100644 index 00000000..2ca31b20 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_multiple_arguments/require_error_multiple_arguments_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check.sol b/examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check.sol new file mode 100644 index 00000000..0f77e252 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check.sol @@ -0,0 +1,19 @@ +// The purpose of this test is to make sure that error constructor call +// stack items are popped from the stack in the success branch, i.e. when +// require condition is true. +contract C { + error E(uint, uint, uint, function(uint256) external pure returns (uint256)); + uint public x; + + function e(uint256 y) external pure returns (uint256) { + return y; + } + + function f(bool condition, uint a, uint b, uint c) public { + require(condition, E(a, b, c, this.e)); + x = b; + } +} +// ---- +// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 -> +// x() -> 4242 diff --git a/examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check_standard_input.json b/examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check_standard_input.json new file mode 100644 index 00000000..ded9b9ed --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_stack_check/require_error_stack_check_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal.sol b/examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal.sol new file mode 100644 index 00000000..6e72253e --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal.sol @@ -0,0 +1,18 @@ +error CustomError(string); + +contract C +{ + function f() external pure + { + require(false, CustomError("errorReason")); + } + + function g() external pure + { + require(false, CustomError("anotherReason")); + } +} + +// ---- +// f() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000b", hex"6572726f72526561736f6e000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000d", hex"616e6f74686572526561736f6e00000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal_standard_input.json b/examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal_standard_input.json new file mode 100644 index 00000000..46c761bc --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_string_literal/require_error_string_literal_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory.sol b/examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory.sol new file mode 100644 index 00000000..15178d85 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory.sol @@ -0,0 +1,20 @@ +error CustomError(string); + +contract C +{ + function f() external pure + { + string memory reason = "errorReason"; + require(false, CustomError(reason)); + } + + function g() external pure + { + string memory reason = "anotherReason"; + require(false, CustomError(reason)); + } +} + +// ---- +// f() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000b", hex"6572726f72526561736f6e000000000000000000000000000000000000000000" +// g() -> FAILURE, hex"8d6ea8be", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"000000000000000000000000000000000000000000000000000000000000000d", hex"616e6f74686572526561736f6e00000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory_standard_input.json b/examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory_standard_input.json new file mode 100644 index 00000000..635dda66 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_string_memory/require_error_string_memory_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_error_uint256/require_error_uint256.sol b/examples/test/semanticTests/errors_require_error_uint256/require_error_uint256.sol new file mode 100644 index 00000000..3b8915f8 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_uint256/require_error_uint256.sol @@ -0,0 +1,18 @@ +error CustomError(uint256); + +contract C +{ + function f() external pure + { + require(false, CustomError(1)); + } + + function g() external pure + { + require(false, CustomError(2)); + } +} + +// ---- +// f() -> FAILURE, hex"110b3655", 1 +// g() -> FAILURE, hex"110b3655", 2 diff --git a/examples/test/semanticTests/errors_require_error_uint256/require_error_uint256_standard_input.json b/examples/test/semanticTests/errors_require_error_uint256/require_error_uint256_standard_input.json new file mode 100644 index 00000000..c7699989 --- /dev/null +++ b/examples/test/semanticTests/errors_require_error_uint256/require_error_uint256_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_require_inherited_error/require_inherited_error.sol b/examples/test/semanticTests/errors_require_inherited_error/require_inherited_error.sol new file mode 100644 index 00000000..33cf0e96 --- /dev/null +++ b/examples/test/semanticTests/errors_require_inherited_error/require_inherited_error.sol @@ -0,0 +1,15 @@ +contract Base +{ + error CustomError(uint256, string, uint256); +} + +contract C is Base +{ + function f() external pure + { + require(false, CustomError(1, "two", 3)); + } +} + +// ---- +// f() -> FAILURE, hex"11a1077e", hex"0000000000000000000000000000000000000000000000000000000000000001", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"74776f0000000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_require_inherited_error/require_inherited_error_standard_input.json b/examples/test/semanticTests/errors_require_inherited_error/require_inherited_error_standard_input.json new file mode 100644 index 00000000..bda462ce --- /dev/null +++ b/examples/test/semanticTests/errors_require_inherited_error/require_inherited_error_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_revert_conversion/revert_conversion.sol b/examples/test/semanticTests/errors_revert_conversion/revert_conversion.sol new file mode 100644 index 00000000..bef34704 --- /dev/null +++ b/examples/test/semanticTests/errors_revert_conversion/revert_conversion.sol @@ -0,0 +1,10 @@ +error E(string a, uint[] b); +contract C { + uint[] x; + function f() public { + x.push(7); + revert E("abc", x); + } +} +// ---- +// f() -> FAILURE, hex"59e4d4df", 0x40, 0x80, 3, "abc", 1, 7 diff --git a/examples/test/semanticTests/errors_revert_conversion/revert_conversion_standard_input.json b/examples/test/semanticTests/errors_revert_conversion/revert_conversion_standard_input.json new file mode 100644 index 00000000..a687e321 --- /dev/null +++ b/examples/test/semanticTests/errors_revert_conversion/revert_conversion_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_simple/simple.sol b/examples/test/semanticTests/errors_simple/simple.sol new file mode 100644 index 00000000..809b10c5 --- /dev/null +++ b/examples/test/semanticTests/errors_simple/simple.sol @@ -0,0 +1,8 @@ +error E(uint a, uint b); +contract C { + function f() public pure { + revert E(2, 7); + } +} +// ---- +// f() -> FAILURE, hex"85208890", 2, 7 diff --git a/examples/test/semanticTests/errors_simple/simple_standard_input.json b/examples/test/semanticTests/errors_simple/simple_standard_input.json new file mode 100644 index 00000000..c2a4471c --- /dev/null +++ b/examples/test/semanticTests/errors_simple/simple_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_small_error_optimization/small_error_optimization.sol b/examples/test/semanticTests/errors_small_error_optimization/small_error_optimization.sol new file mode 100644 index 00000000..8128193b --- /dev/null +++ b/examples/test/semanticTests/errors_small_error_optimization/small_error_optimization.sol @@ -0,0 +1,22 @@ +error E(); +contract A { + uint8[] x; + function f() public { + for (uint i = 0; i < 100; ++i) + x.push(uint8(i)); + revert E(); + } +} +contract B { + function f() public { + (new A()).f(); + } +} +// ---- +// f() -> FAILURE, hex"92bbf6e8" +// gas irOptimized: 221918 +// gas irOptimized code: 42800 +// gas legacy: 233752 +// gas legacy code: 38000 +// gas legacyOptimized: 224863 +// gas legacyOptimized code: 34200 diff --git a/examples/test/semanticTests/errors_small_error_optimization/small_error_optimization_standard_input.json b/examples/test/semanticTests/errors_small_error_optimization/small_error_optimization_standard_input.json new file mode 100644 index 00000000..7b5ec419 --- /dev/null +++ b/examples/test/semanticTests/errors_small_error_optimization/small_error_optimization_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_using_structs/using_structs.sol b/examples/test/semanticTests/errors_using_structs/using_structs.sol new file mode 100644 index 00000000..e04e4b1c --- /dev/null +++ b/examples/test/semanticTests/errors_using_structs/using_structs.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; +struct S { uint a; string b; } +error E(uint a, S s, uint b); +contract C { + S s; + function f(bool c) public { + if (c) { + s.a = 9; + s.b = "abc"; + revert E(2, s, 7); + } else { + revert E({b: 7, a: 2, s: S({b: "abc", a: 9})}); + } + } +} +// ---- +// f(bool): true -> FAILURE, hex"e96e07f0", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000007", hex"0000000000000000000000000000000000000000000000000000000000000009", hex"0000000000000000000000000000000000000000000000000000000000000040", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"6162630000000000000000000000000000000000000000000000000000000000" +// f(bool): false -> FAILURE, hex"e96e07f0", hex"0000000000000000000000000000000000000000000000000000000000000002", hex"0000000000000000000000000000000000000000000000000000000000000060", hex"0000000000000000000000000000000000000000000000000000000000000007", hex"0000000000000000000000000000000000000000000000000000000000000009", hex"0000000000000000000000000000000000000000000000000000000000000040", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"6162630000000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_using_structs/using_structs_standard_input.json b/examples/test/semanticTests/errors_using_structs/using_structs_standard_input.json new file mode 100644 index 00000000..28ba0662 --- /dev/null +++ b/examples/test/semanticTests/errors_using_structs/using_structs_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_via_contract_type/via_contract_type.sol b/examples/test/semanticTests/errors_via_contract_type/via_contract_type.sol new file mode 100644 index 00000000..09f60e65 --- /dev/null +++ b/examples/test/semanticTests/errors_via_contract_type/via_contract_type.sol @@ -0,0 +1,16 @@ +contract A { + error E(uint); +} +contract X { + error E(string); +} +contract B is A { + function f() public pure { revert E(1); } + function g() public pure { revert A.E(1); } + function h() public pure { revert X.E("abc"); } + +} +// ---- +// f() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000001" +// g() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000001" +// h() -> FAILURE, hex"3e9992c9", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000003", hex"6162630000000000000000000000000000000000000000000000000000000000" diff --git a/examples/test/semanticTests/errors_via_contract_type/via_contract_type_standard_input.json b/examples/test/semanticTests/errors_via_contract_type/via_contract_type_standard_input.json new file mode 100644 index 00000000..e8b13e5a --- /dev/null +++ b/examples/test/semanticTests/errors_via_contract_type/via_contract_type_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_via_import/via_import.sol b/examples/test/semanticTests/errors_via_import/via_import.sol new file mode 100644 index 00000000..eb54e5b4 --- /dev/null +++ b/examples/test/semanticTests/errors_via_import/via_import.sol @@ -0,0 +1,23 @@ +==== Source: s1.sol ==== +error E(uint); +==== Source: s2.sol ==== +import "s1.sol" as S; +==== Source: s3.sol ==== +import "s1.sol" as S; +import "s2.sol" as T; +import "s1.sol"; +contract C { + function x() public pure { + revert E(1); + } + function y() public pure { + revert S.E(2); + } + function z() public pure { + revert T.S.E(3); + } +} +// ---- +// x() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000001" +// y() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000002" +// z() -> FAILURE, hex"002ff067", hex"0000000000000000000000000000000000000000000000000000000000000003" diff --git a/examples/test/semanticTests/errors_via_import/via_import_standard_input.json b/examples/test/semanticTests/errors_via_import/via_import_standard_input.json new file mode 100644 index 00000000..2dc7978f --- /dev/null +++ b/examples/test/semanticTests/errors_via_import/via_import_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + }, + "require_error_evaluation_order_2.sol": { + "content": "contract C {\n uint y;\n function g(bool x) internal returns (bool) {\n y = 42;\n return x;\n }\n error E(uint256);\n function h() internal returns (uint256) { return y; }\n function f(bool c) public {\n require(g(c), E(h()));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n" + }, + "weird_name.sol": { + "content": "error error(uint a);\ncontract C {\n function f() public pure {\n revert error(2);\n }\n}\n// ----\n// f() -> FAILURE, hex\"b48fb6cf\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n" + }, + "require_error_evaluation_order_1.sol": { + "content": "contract C\n{\n error E(uint);\n\n function r() internal returns (uint)\n {\n assembly { mstore(0, 7) return (0, 32) }\n return 42;\n }\n\n function f() public returns (uint)\n {\n require(false, E(r()));\n return 42;\n }\n\n function g() public returns (uint)\n {\n require(true, E(r()));\n return 42;\n }\n}\n\n// ----\n// f() -> 7\n// g() -> 7\n" + }, + "require_error_function_join_control_flow.sol": { + "content": "contract C {\n uint x = 0;\n uint y = 42;\n error E(uint);\n function f(bool c) public returns (uint256, uint256, uint256) {\n uint z = x;\n if (y == 42) {\n x = 21;\n } else {\n require(c, E(y));\n }\n y /= 2;\n return (x,y,z);\n }\n}\n// ----\n// f(bool): true -> 0x15, 0x15, 0\n// f(bool): false -> FAILURE, hex\"002ff067\", 21\n" + }, + "via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport \"s1.sol\" as S;\n==== Source: s3.sol ====\nimport \"s1.sol\" as S;\nimport \"s2.sol\" as T;\nimport \"s1.sol\";\ncontract C {\n function x() public pure {\n revert E(1);\n }\n function y() public pure {\n revert S.E(2);\n }\n function z() public pure {\n revert T.S.E(3);\n }\n}\n// ----\n// x() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// y() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// z() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/errors_weird_name/weird_name.sol b/examples/test/semanticTests/errors_weird_name/weird_name.sol new file mode 100644 index 00000000..2466d6e2 --- /dev/null +++ b/examples/test/semanticTests/errors_weird_name/weird_name.sol @@ -0,0 +1,8 @@ +error error(uint a); +contract C { + function f() public pure { + revert error(2); + } +} +// ---- +// f() -> FAILURE, hex"b48fb6cf", hex"0000000000000000000000000000000000000000000000000000000000000002" diff --git a/examples/test/semanticTests/errors_weird_name/weird_name_standard_input.json b/examples/test/semanticTests/errors_weird_name/weird_name_standard_input.json new file mode 100644 index 00000000..b0b092d9 --- /dev/null +++ b/examples/test/semanticTests/errors_weird_name/weird_name_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "require_error_string_literal.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(\"errorReason\"));\n }\n\n function g() external pure\n {\n require(false, CustomError(\"anotherReason\"));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_error_multiple_arguments.sol": { + "content": "error CustomError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, CustomError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_error_function_pointer_parameter.sol": { + "content": "error CustomError(function(uint256) external pure returns (uint256));\n\ncontract C\n{\n function e(uint256 x) external pure returns (uint256)\n {\n return x;\n }\n\n function f() external view\n {\n // more than one stack slot\n require(false, CustomError(this.e));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"271b1dfa\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79ef37cdc8e0000000000000000\"\n" + }, + "require_error_uint256.sol": { + "content": "error CustomError(uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, CustomError(1));\n }\n\n function g() external pure\n {\n require(false, CustomError(2));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"110b3655\", 1\n// g() -> FAILURE, hex\"110b3655\", 2\n" + }, + "require_error_condition_evaluated_only_once.sol": { + "content": "contract C {\n uint256 counter = 0;\n\n error CustomError(uint256);\n\n function getCounter() public view returns (uint256) {\n return counter;\n }\n\n function g(bool condition) internal returns (bool) {\n counter++;\n return condition;\n }\n\n function f(bool condition) external {\n require(g(condition), CustomError(counter));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"110b3655\", 1\n// getCounter() -> 0\n// f(bool): true ->\n// getCounter() -> 1\n" + }, + "error_in_library_and_interface.sol": { + "content": "error E(uint a);\nlibrary L {\n error E(uint a, uint b);\n}\ninterface I {\n error E(uint a, uint b, uint c);\n}\ncontract C {\n function f() public pure {\n revert E(1);\n }\n function g() public pure {\n revert L.E(1, 2);\n }\n function h() public pure {\n revert I.E(1, 2, 3);\n }\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"85208890\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n// h() -> FAILURE, hex\"7924ea7c\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000003\"\n" + }, + "error_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n error E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n revert E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> FAILURE, hex\"f42f106d\", 0x40, 0xff, 1, 0xffff\n" + }, + "named_parameters_shadowing_types.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n enum EnumType {A, B, C}\n\n struct StructType {\n uint x;\n }\n\n error E1(StructType StructType);\n error E2(EnumType StructType, StructType EnumType);\n\n function f() public {\n revert E1({StructType: StructType(42)});\n }\n\n function g() public {\n revert E2({EnumType: StructType(42), StructType: EnumType.B});\n }\n}\n// ----\n// f() -> FAILURE, hex\"33a54193\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n// g() -> FAILURE, hex\"374b9387\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"000000000000000000000000000000000000000000000000000000000000002a\"\n" + }, + "require_error_string_memory.sol": { + "content": "error CustomError(string);\n\ncontract C\n{\n function f() external pure\n {\n string memory reason = \"errorReason\";\n require(false, CustomError(reason));\n }\n\n function g() external pure\n {\n string memory reason = \"anotherReason\";\n require(false, CustomError(reason));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000b\", hex\"6572726f72526561736f6e000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"8d6ea8be\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000d\", hex\"616e6f74686572526561736f6e00000000000000000000000000000000000000\"\n" + }, + "require_inherited_error.sol": { + "content": "contract Base\n{\n error CustomError(uint256, string, uint256);\n}\n\ncontract C is Base\n{\n function f() external pure\n {\n require(false, CustomError(1, \"two\", 3));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"11a1077e\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n" + }, + "require_different_errors_same_parameters.sol": { + "content": "error AnError(uint256, string, uint256);\nerror AnotherError(uint256, string, uint256);\n\ncontract C\n{\n function f() external pure\n {\n require(false, AnError(1, \"two\", 3));\n }\n\n function g() external pure\n {\n require(false, AnotherError(4, \"five\", 6));\n }\n}\n\n// ----\n// f() -> FAILURE, hex\"f55fefe3\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"74776f0000000000000000000000000000000000000000000000000000000000\"\n// g() -> FAILURE, hex\"44a06798\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000006\", hex\"0000000000000000000000000000000000000000000000000000000000000004\", hex\"6669766500000000000000000000000000000000000000000000000000000000\"\n" + }, + "using_structs.sol": { + "content": "pragma abicoder v2;\nstruct S { uint a; string b; }\nerror E(uint a, S s, uint b);\ncontract C {\n S s;\n function f(bool c) public {\n if (c) {\n s.a = 9;\n s.b = \"abc\";\n revert E(2, s, 7);\n } else {\n revert E({b: 7, a: 2, s: S({b: \"abc\", a: 9})});\n }\n }\n}\n// ----\n// f(bool): true -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n// f(bool): false -> FAILURE, hex\"e96e07f0\", hex\"0000000000000000000000000000000000000000000000000000000000000002\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"0000000000000000000000000000000000000000000000000000000000000007\", hex\"0000000000000000000000000000000000000000000000000000000000000009\", hex\"0000000000000000000000000000000000000000000000000000000000000040\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "via_contract_type.sol": { + "content": "contract A {\n error E(uint);\n}\ncontract X {\n error E(string);\n}\ncontract B is A {\n function f() public pure { revert E(1); }\n function g() public pure { revert A.E(1); }\n function h() public pure { revert X.E(\"abc\"); }\n\n}\n// ----\n// f() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// g() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// h() -> FAILURE, hex\"3e9992c9\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000003\", hex\"6162630000000000000000000000000000000000000000000000000000000000\"\n" + }, + "revert_conversion.sol": { + "content": "error E(string a, uint[] b);\ncontract C {\n uint[] x;\n function f() public {\n x.push(7);\n revert E(\"abc\", x);\n }\n}\n// ----\n// f() -> FAILURE, hex\"59e4d4df\", 0x40, 0x80, 3, \"abc\", 1, 7\n" + }, + "errors_by_parameter_type.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint256 a;\n bool b;\n string s;\n}\n\nerror E();\nerror E1(uint256);\nerror E2(string);\nerror E3(S);\nerror E4(address);\nerror E5(function() external pure);\n\ncontract C {\n function a() external pure {\n require(false, E());\n }\n function b() external pure {\n require(false, E1(1));\n }\n function c() external pure {\n require(false, E2(\"string literal\"));\n }\n function d() external pure {\n require(false, E3(S(1, true, \"string literal\")));\n }\n function e() external view {\n require(false, E4(address(this)));\n }\n function f() external view {\n require(false, E5(this.a));\n }\n}\n\n// ====\n// compileViaYul: true\n// ----\n// a() -> FAILURE, hex\"92bbf6e8\"\n// b() -> FAILURE, hex\"47e26897\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// c() -> FAILURE, hex\"8f372c34\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// d() -> FAILURE, hex\"5717173e\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000001\", hex\"0000000000000000000000000000000000000000000000000000000000000060\", hex\"000000000000000000000000000000000000000000000000000000000000000e\", hex\"737472696e67206c69746572616c000000000000000000000000000000000000\"\n// e() -> FAILURE, hex\"7efef9ea\", hex\"000000000000000000000000c06afe3a8444fc0004668591e8306bfb9968e79e\"\n// f() -> FAILURE, hex\"0c3f12eb\", hex\"c06afe3a8444fc0004668591e8306bfb9968e79e0dbe671f0000000000000000\"\n" + }, + "require_error_stack_check.sol": { + "content": "// The purpose of this test is to make sure that error constructor call\n// stack items are popped from the stack in the success branch, i.e. when\n// require condition is true.\ncontract C {\n error E(uint, uint, uint, function(uint256) external pure returns (uint256));\n uint public x;\n\n function e(uint256 y) external pure returns (uint256) {\n return y;\n }\n\n function f(bool condition, uint a, uint b, uint c) public {\n require(condition, E(a, b, c, this.e));\n x = b;\n }\n}\n// ----\n// f(bool,uint256,uint256,uint256): true, 42, 4242, 424242 ->\n// x() -> 4242\n" + }, + "small_error_optimization.sol": { + "content": "error E();\ncontract A {\n\tuint8[] x;\n\tfunction f() public {\n\t\tfor (uint i = 0; i < 100; ++i)\n\t\t\tx.push(uint8(i));\n\t\trevert E();\n\t}\n}\ncontract B {\n\tfunction f() public {\n\t\t(new A()).f();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"92bbf6e8\"\n// gas irOptimized: 221918\n// gas irOptimized code: 42800\n// gas legacy: 233752\n// gas legacy code: 38000\n// gas legacyOptimized: 224863\n// gas legacyOptimized code: 34200\n" + }, + "error_selector.sol": { + "content": "library L {\n error E();\n}\nlibrary S {\n error E(uint);\n}\nlibrary T {\n error E();\n}\n\nerror E();\n\ninterface I {\n error E();\n function f() external pure;\n}\n\ncontract D {\n error F();\n}\n\ncontract C is D {\n function test1() public pure returns (bytes4, bytes4, bytes4, bytes4) {\n assert(L.E.selector == T.E.selector);\n assert(L.E.selector != S.E.selector);\n assert(E.selector == L.E.selector);\n assert(I.E.selector == L.E.selector);\n return (L.E.selector, S.E.selector, E.selector, I.E.selector);\n }\n\n bytes4 s1 = L.E.selector;\n bytes4 s2 = S.E.selector;\n bytes4 s3 = T.E.selector;\n bytes4 s4 = I.E.selector;\n function test2() external returns (bytes4, bytes4, bytes4, bytes4) {\n return (s1, s2, s3, s4);\n }\n\n function test3() external returns (bytes4) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test2() -> 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x2ff06700000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000, 0x92bbf6e800000000000000000000000000000000000000000000000000000000\n// test3() -> 0x28811f5900000000000000000000000000000000000000000000000000000000\n" + }, + "simple.sol": { + "content": "error E(uint a, uint b);\ncontract C {\n function f() public pure {\n revert E(2, 7);\n }\n}\n// ----\n// f() -> FAILURE, hex\"85208890\", 2, 7\n" + }, + "panic_via_import.sol": { + "content": "==== Source: s1.sol ====\nerror E(uint);\n==== Source: s2.sol ====\nimport { E as Panic } from \"s1.sol\";\ncontract C {\n error E(uint);\n function a() public pure {\n revert Panic(1);\n }\n function b() public pure {\n revert E(1);\n }\n}\n// ----\n// a() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n// b() -> FAILURE, hex\"002ff067\", hex\"0000000000000000000000000000000000000000000000000000000000000001\"\n" + }, + "require_error_evaluation_order_3.sol": { + "content": "contract C {\n string failureMessage = \"Failure Message\";\n function g(bool x) internal returns (bool) {\n failureMessage = \"Intercepted failure message\";\n return x;\n }\n function h() internal returns (string memory) { return failureMessage; }\n function f(bool c) public {\n require(g(c), h());\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x1b, \"Intercepted failure message\"\n// f(bool): true ->\n" + }, + "require_error_evaluation_order_2.sol": { + "content": "contract C {\n uint y;\n function g(bool x) internal returns (bool) {\n y = 42;\n return x;\n }\n error E(uint256);\n function h() internal returns (uint256) { return y; }\n function f(bool c) public {\n require(g(c), E(h()));\n }\n}\n\n// ----\n// f(bool): false -> FAILURE, hex\"002ff067\", 42\n// f(bool): true ->\n" + }, + "weird_name.sol": { + "content": "error error(uint a);\ncontract C {\n function f() public pure {\n revert error(2);\n }\n}\n// ----\n// f() -> FAILURE, hex\"b48fb6cf\", hex\"0000000000000000000000000000000000000000000000000000000000000002\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event/event.sol b/examples/test/semanticTests/events_event/event.sol new file mode 100644 index 00000000..0f70dc65 --- /dev/null +++ b/examples/test/semanticTests/events_event/event.sol @@ -0,0 +1,21 @@ +contract ClientReceipt { + event Deposit(address indexed _from, bytes32 indexed _id, uint _value); + function deposit(bytes32 _id, bool _manually) public payable { + if (_manually) { + bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f; + uint value = msg.value; + address sender = msg.sender; + assembly { + mstore(0, value) + log3(0, 0x20, s, sender, _id) + } + } else { + emit Deposit(msg.sender, _id, msg.value); + } + } +} +// ---- +// deposit(bytes32,bool), 18 wei: 0x1234, true -> +// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12 +// deposit(bytes32,bool), 18 wei: 0x1234, false -> +// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12 diff --git a/examples/test/semanticTests/events_event/event_standard_input.json b/examples/test/semanticTests/events_event/event_standard_input.json new file mode 100644 index 00000000..60f810aa --- /dev/null +++ b/examples/test/semanticTests/events_event/event_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit.sol b/examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit.sol new file mode 100644 index 00000000..dede5eac --- /dev/null +++ b/examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit.sol @@ -0,0 +1,12 @@ +contract A { + event x(); +} +contract B is A { + function f() public returns (uint) { + emit A.x(); + return 1; + } +} +// ---- +// f() -> 1 +// ~ emit x() diff --git a/examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit_standard_input.json b/examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit_standard_input.json new file mode 100644 index 00000000..1cbd42fc --- /dev/null +++ b/examples/test/semanticTests/events_event_access_through_base_name_emit/event_access_through_base_name_emit_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_anonymous/event_anonymous.sol b/examples/test/semanticTests/events_event_anonymous/event_anonymous.sol new file mode 100644 index 00000000..1aaffa39 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous/event_anonymous.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit() anonymous; + function deposit() public { + emit Deposit(); + } +} +// ---- +// deposit() -> +// ~ emit diff --git a/examples/test/semanticTests/events_event_anonymous/event_anonymous_standard_input.json b/examples/test/semanticTests/events_event_anonymous/event_anonymous_standard_input.json new file mode 100644 index 00000000..cf6f4d43 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous/event_anonymous_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + }, + "event_anonymous.sol": { + "content": "contract ClientReceipt {\n event Deposit() anonymous;\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit \n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision.sol b/examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision.sol new file mode 100644 index 00000000..c4ac4e83 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous; + function deposit(bytes32 _id) public payable { + emit Deposit(0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, _id, msg.value); // 0x2012159c -> 'Deposit(uint256,bytes32,uint256)' + } +} +// ---- +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit : #0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, #0x1234, 0x12 diff --git a/examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision_standard_input.json b/examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision_standard_input.json new file mode 100644 index 00000000..876b8f42 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous_with_signature_collision/event_anonymous_with_signature_collision_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + }, + "event_anonymous.sol": { + "content": "contract ClientReceipt {\n event Deposit() anonymous;\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit \n" + }, + "event_emit_from_a_foreign_contract_same_name.sol": { + "content": "contract C {\n event E(uint256 value);\n}\n\ncontract D {\n event E(uint256 value);\n\n function test() public {\n emit C.E(1);\n emit E(2);\n }\n}\n\n// ----\n// test() ->\n// ~ emit E(uint256): 0x01\n// ~ emit E(uint256): 0x02\n" + }, + "event_indexed_string.sol": { + "content": "contract C {\n string x;\n uint[4] y;\n event E(string indexed r, uint[4] indexed t);\n function deposit() public {\n for (uint i = 0; i < 90; i++)\n bytes(x).push(0);\n for (uint8 i = 0; i < 90; i++)\n bytes(x)[i] = bytes1(i);\n y[0] = 4;\n y[1] = 5;\n y[2] = 6;\n y[3] = 7;\n emit E(x, y);\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81\n// gas irOptimized: 332788\n// gas legacy: 366022\n// gas legacyOptimized: 362429\n" + }, + "event_no_arguments.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit()\n" + }, + "event_anonymous_with_signature_collision.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, _id, msg.value); // 0x2012159c -> 'Deposit(uint256,bytes32,uint256)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, #0x1234, 0x12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2.sol b/examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2.sol new file mode 100644 index 00000000..3d2b3bb7 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2.sol @@ -0,0 +1,10 @@ +contract ClientReceipt { + event Withdraw(uint _value, string owner); + event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous; + function deposit(bytes32 _id) public payable { + emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)' + } +} +// ---- +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit Withdraw(uint256,string): #0x1234, 0x12 diff --git a/examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2_standard_input.json b/examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2_standard_input.json new file mode 100644 index 00000000..7ec79cdc --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous_with_signature_collision2/event_anonymous_with_signature_collision2_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics.sol b/examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics.sol new file mode 100644 index 00000000..a46d9799 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous; + function deposit(bytes32 _id) public payable { + emit Deposit(msg.sender, _id, msg.value, 2, "abc"); + } +} +// ---- +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, "abc" diff --git a/examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics_standard_input.json b/examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics_standard_input.json new file mode 100644 index 00000000..53730556 --- /dev/null +++ b/examples/test/semanticTests/events_event_anonymous_with_topics/event_anonymous_with_topics_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_constructor/event_constructor.sol b/examples/test/semanticTests/events_event_constructor/event_constructor.sol new file mode 100644 index 00000000..bbb66cba --- /dev/null +++ b/examples/test/semanticTests/events_event_constructor/event_constructor.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(address indexed _from, bytes32 indexed _id, uint _value); + constructor() { + emit Deposit(msg.sender, bytes32("abc"), 7); + } +} +// ---- +// constructor() +// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #"abc", 0x07 diff --git a/examples/test/semanticTests/events_event_constructor/event_constructor_standard_input.json b/examples/test/semanticTests/events_event_constructor/event_constructor_standard_input.json new file mode 100644 index 00000000..8bc2041f --- /dev/null +++ b/examples/test/semanticTests/events_event_constructor/event_constructor_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory.sol b/examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory.sol new file mode 100644 index 00000000..4dd63819 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory.sol @@ -0,0 +1,13 @@ +contract C { + event E(uint[]); + function createEvent(uint x) public { + uint[] memory arr = new uint[](3); + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c diff --git a/examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory_standard_input.json b/examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory_standard_input.json new file mode 100644 index 00000000..115237fb --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_memory/event_dynamic_array_memory_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2.sol b/examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2.sol new file mode 100644 index 00000000..8bde9a2a --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; +contract C { + event E(uint[]); + function createEvent(uint x) public { + uint[] memory arr = new uint[](3); + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c diff --git a/examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2_standard_input.json b/examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2_standard_input.json new file mode 100644 index 00000000..7f2c9c31 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_memory_v2/event_dynamic_array_memory_v2_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage.sol b/examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage.sol new file mode 100644 index 00000000..bdd355f6 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage.sol @@ -0,0 +1,18 @@ +contract C { + event E(uint[]); + uint[] arr; + function createEvent(uint x) public { + while (arr.length < 3) + arr.push(); + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c +// gas irOptimized: 114231 +// gas legacy: 116313 +// gas legacyOptimized: 114407 diff --git a/examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage_standard_input.json b/examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage_standard_input.json new file mode 100644 index 00000000..e21fbe35 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_storage/event_dynamic_array_storage_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2.sol b/examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2.sol new file mode 100644 index 00000000..cecf31b4 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2.sol @@ -0,0 +1,19 @@ +pragma abicoder v2; +contract C { + event E(uint[]); + uint[] arr; + function createEvent(uint x) public { + while (arr.length < 3) + arr.push(); + arr[0] = x; + arr[1] = x + 1; + arr[2] = x + 2; + emit E(arr); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c +// gas irOptimized: 114231 +// gas legacy: 116313 +// gas legacyOptimized: 114407 diff --git a/examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2_standard_input.json b/examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2_standard_input.json new file mode 100644 index 00000000..dd7d53be --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_array_storage_v2/event_dynamic_array_storage_v2_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2.sol b/examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2.sol new file mode 100644 index 00000000..00fda110 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; +contract C { + event E(uint[][]); + function createEvent(uint x) public { + uint[][] memory arr = new uint[][](2); + arr[0] = new uint[](2); + arr[1] = new uint[](2); + arr[0][0] = x; + arr[0][1] = x + 1; + arr[1][0] = x + 2; + arr[1][1] = x + 3; + emit E(arr); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d diff --git a/examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2_standard_input.json b/examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2_standard_input.json new file mode 100644 index 00000000..759eea28 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_nested_array_memory_v2/event_dynamic_nested_array_memory_v2_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2.sol b/examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2.sol new file mode 100644 index 00000000..1ff58d65 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; +contract C { + event E(uint[][]); + uint[][] arr; + function createEvent(uint x) public { + arr.push(new uint[](2)); + arr.push(new uint[](2)); + arr[0][0] = x; + arr[0][1] = x + 1; + arr[1][0] = x + 2; + arr[1][1] = x + 3; + emit E(arr); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d +// gas irOptimized: 185148 +// gas legacy: 187493 +// gas legacyOptimized: 184548 diff --git a/examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2_standard_input.json b/examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2_standard_input.json new file mode 100644 index 00000000..8a3f0aa1 --- /dev/null +++ b/examples/test/semanticTests/events_event_dynamic_nested_array_storage_v2/event_dynamic_nested_array_storage_v2_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit/event_emit.sol b/examples/test/semanticTests/events_event_emit/event_emit.sol new file mode 100644 index 00000000..07224d97 --- /dev/null +++ b/examples/test/semanticTests/events_event_emit/event_emit.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(address indexed _from, bytes32 indexed _id, uint _value); + function deposit(bytes32 _id) public payable { + emit Deposit(msg.sender, _id, msg.value); + } +} +// ---- +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12 diff --git a/examples/test/semanticTests/events_event_emit/event_emit_standard_input.json b/examples/test/semanticTests/events_event_emit/event_emit_standard_input.json new file mode 100644 index 00000000..2decf74b --- /dev/null +++ b/examples/test/semanticTests/events_event_emit/event_emit_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + }, + "event_anonymous.sol": { + "content": "contract ClientReceipt {\n event Deposit() anonymous;\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit \n" + }, + "event_emit_from_a_foreign_contract_same_name.sol": { + "content": "contract C {\n event E(uint256 value);\n}\n\ncontract D {\n event E(uint256 value);\n\n function test() public {\n emit C.E(1);\n emit E(2);\n }\n}\n\n// ----\n// test() ->\n// ~ emit E(uint256): 0x01\n// ~ emit E(uint256): 0x02\n" + }, + "event_indexed_string.sol": { + "content": "contract C {\n string x;\n uint[4] y;\n event E(string indexed r, uint[4] indexed t);\n function deposit() public {\n for (uint i = 0; i < 90; i++)\n bytes(x).push(0);\n for (uint8 i = 0; i < 90; i++)\n bytes(x)[i] = bytes1(i);\n y[0] = 4;\n y[1] = 5;\n y[2] = 6;\n y[3] = 7;\n emit E(x, y);\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81\n// gas irOptimized: 332788\n// gas legacy: 366022\n// gas legacyOptimized: 362429\n" + }, + "event_no_arguments.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit()\n" + }, + "event_anonymous_with_signature_collision.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, _id, msg.value); // 0x2012159c -> 'Deposit(uint256,bytes32,uint256)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x2012159ca6b6372f102c535a4814d13a00bfc5568ddfd72151364061b00355d1, #0x1234, 0x12\n" + }, + "event_emit.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level.sol b/examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level.sol new file mode 100644 index 00000000..b698bb80 --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level.sol @@ -0,0 +1,10 @@ +event Deposit(address indexed _from, bytes32 indexed _id, uint _value); + +contract ClientReceipt { + function deposit(bytes32 _id) public payable { + emit Deposit(msg.sender, _id, msg.value); + } +} +// ---- +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12 diff --git a/examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level_standard_input.json b/examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level_standard_input.json new file mode 100644 index 00000000..606c6dae --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_file_level/event_emit_file_level_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract.sol b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract.sol new file mode 100644 index 00000000..fcd7b6f4 --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract.sol @@ -0,0 +1,13 @@ +contract C { + event E(); +} + +contract D { + function test() public { + emit C.E(); + } +} + +// ---- +// test() -> +// ~ emit E() diff --git a/examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract_standard_input.json b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract_standard_input.json new file mode 100644 index 00000000..3fed30bd --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract/event_emit_from_a_foreign_contract_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name.sol b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name.sol new file mode 100644 index 00000000..05c03c20 --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name.sol @@ -0,0 +1,17 @@ +contract C { + event E(uint256 value); +} + +contract D { + event E(uint256 value); + + function test() public { + emit C.E(1); + emit E(2); + } +} + +// ---- +// test() -> +// ~ emit E(uint256): 0x01 +// ~ emit E(uint256): 0x02 diff --git a/examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name_standard_input.json b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name_standard_input.json new file mode 100644 index 00000000..1ae2960d --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_from_a_foreign_contract_same_name/event_emit_from_a_foreign_contract_same_name_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + }, + "event_anonymous.sol": { + "content": "contract ClientReceipt {\n event Deposit() anonymous;\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit \n" + }, + "event_emit_from_a_foreign_contract_same_name.sol": { + "content": "contract C {\n event E(uint256 value);\n}\n\ncontract D {\n event E(uint256 value);\n\n function test() public {\n emit C.E(1);\n emit E(2);\n }\n}\n\n// ----\n// test() ->\n// ~ emit E(uint256): 0x01\n// ~ emit E(uint256): 0x02\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract.sol b/examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract.sol new file mode 100644 index 00000000..61e1bbdd --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract.sol @@ -0,0 +1,25 @@ +contract D { + event Deposit(address indexed _from, bytes32 indexed _id, uint _value); + function deposit(bytes32 _id) public payable { + emit Deposit(msg.sender, _id, msg.value); + } +} +contract C { + D d; + constructor() { + d = new D(); + } + function deposit(bytes32 _id) public payable { + d.deposit(_id); + } +} +// ---- +// constructor() -> +// gas irOptimized: 113970 +// gas irOptimized code: 51400 +// gas legacy: 119791 +// gas legacy code: 125200 +// gas legacyOptimized: 114187 +// gas legacyOptimized code: 57400 +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00 diff --git a/examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract_standard_input.json b/examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract_standard_input.json new file mode 100644 index 00000000..681f93b3 --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_from_other_contract/event_emit_from_other_contract_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library.sol b/examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library.sol new file mode 100644 index 00000000..9e24287a --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library.sol @@ -0,0 +1,19 @@ +interface I { + event E(); +} + +library L { + function f() internal { + emit I.E(); + } +} + +contract C { + function g() public { + L.f(); + } +} + +// ---- +// g() -> +// ~ emit E() diff --git a/examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library_standard_input.json b/examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library_standard_input.json new file mode 100644 index 00000000..3aa658d3 --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_interface_event_via_library/event_emit_interface_event_via_library_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface.sol b/examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface.sol new file mode 100644 index 00000000..7268e9ac --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface.sol @@ -0,0 +1,13 @@ +interface I { + event Event(address indexed _from, uint256 _value); +} + +contract C { + function emitEvent(uint256 _value) public { + emit I.Event(msg.sender, _value); + } +} + +// ---- +// emitEvent(uint256): 100 -> +// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64 diff --git a/examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface_standard_input.json b/examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface_standard_input.json new file mode 100644 index 00000000..b16d14cf --- /dev/null +++ b/examples/test/semanticTests/events_event_emit_via_interface/event_emit_via_interface_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_indexed_function/event_indexed_function.sol b/examples/test/semanticTests/events_event_indexed_function/event_indexed_function.sol new file mode 100644 index 00000000..ea757415 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_function/event_indexed_function.sol @@ -0,0 +1,9 @@ +contract C { + event Test(function() external indexed); + function f() public { + emit Test(this.f); + } +} +// ---- +// f() -> +// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000 diff --git a/examples/test/semanticTests/events_event_indexed_function/event_indexed_function_standard_input.json b/examples/test/semanticTests/events_event_indexed_function/event_indexed_function_standard_input.json new file mode 100644 index 00000000..07f3f2eb --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_function/event_indexed_function_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2.sol b/examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2.sol new file mode 100644 index 00000000..d4c47e86 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2.sol @@ -0,0 +1,15 @@ +contract C { + event TestA(function() external indexed); + event TestB(function(uint256) external indexed); + function f1() public { + emit TestA(this.f1); + } + function f2(uint256 a) public { + emit TestB(this.f2); + } +} +// ---- +// f1() -> +// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000 +// f2(uint256): 1 -> +// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000 diff --git a/examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2_standard_input.json b/examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2_standard_input.json new file mode 100644 index 00000000..829614c4 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_function2/event_indexed_function2_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed.sol b/examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed.sol new file mode 100644 index 00000000..ad753ef1 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed.sol @@ -0,0 +1,16 @@ +contract C { + // Indexed parameters are always listed first in the output. + // The data is the ABI encoding of just the non-indexed parameters, + // so putting the indexed parameters "in between" would mess + // up the offsets for the reader. + event E(uint a, uint indexed r, uint b, bytes c); + function deposit() public { + emit E(1, 2, 3, "def"); + } +} +// ---- +// deposit() -> +// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, "def" +// gas irOptimized: 23709 +// gas legacy: 24342 +// gas legacyOptimized: 23753 diff --git a/examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed_standard_input.json b/examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed_standard_input.json new file mode 100644 index 00000000..e377aa31 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_mixed/event_indexed_mixed_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_indexed_string/event_indexed_string.sol b/examples/test/semanticTests/events_event_indexed_string/event_indexed_string.sol new file mode 100644 index 00000000..2e4b1106 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_string/event_indexed_string.sol @@ -0,0 +1,22 @@ +contract C { + string x; + uint[4] y; + event E(string indexed r, uint[4] indexed t); + function deposit() public { + for (uint i = 0; i < 90; i++) + bytes(x).push(0); + for (uint8 i = 0; i < 90; i++) + bytes(x)[i] = bytes1(i); + y[0] = 4; + y[1] = 5; + y[2] = 6; + y[3] = 7; + emit E(x, y); + } +} +// ---- +// deposit() -> +// ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 +// gas irOptimized: 332788 +// gas legacy: 366022 +// gas legacyOptimized: 362429 diff --git a/examples/test/semanticTests/events_event_indexed_string/event_indexed_string_standard_input.json b/examples/test/semanticTests/events_event_indexed_string/event_indexed_string_standard_input.json new file mode 100644 index 00000000..abe17a02 --- /dev/null +++ b/examples/test/semanticTests/events_event_indexed_string/event_indexed_string_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + }, + "event_anonymous.sol": { + "content": "contract ClientReceipt {\n event Deposit() anonymous;\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit \n" + }, + "event_emit_from_a_foreign_contract_same_name.sol": { + "content": "contract C {\n event E(uint256 value);\n}\n\ncontract D {\n event E(uint256 value);\n\n function test() public {\n emit C.E(1);\n emit E(2);\n }\n}\n\n// ----\n// test() ->\n// ~ emit E(uint256): 0x01\n// ~ emit E(uint256): 0x02\n" + }, + "event_indexed_string.sol": { + "content": "contract C {\n string x;\n uint[4] y;\n event E(string indexed r, uint[4] indexed t);\n function deposit() public {\n for (uint i = 0; i < 90; i++)\n bytes(x).push(0);\n for (uint8 i = 0; i < 90; i++)\n bytes(x)[i] = bytes1(i);\n y[0] = 4;\n y[1] = 5;\n y[2] = 6;\n y[3] = 7;\n emit E(x, y);\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81\n// gas irOptimized: 332788\n// gas legacy: 366022\n// gas legacyOptimized: 362429\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data.sol b/examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data.sol new file mode 100644 index 00000000..b7926a84 --- /dev/null +++ b/examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(address _from, bytes32 _id, uint _value, bool _flag); + function deposit(bytes32 _id) public payable { + emit Deposit(msg.sender, _id, msg.value, true); + } +} +// ---- +// deposit(bytes32), 18 wei: 0x1234 -> +// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true diff --git a/examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data_standard_input.json b/examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data_standard_input.json new file mode 100644 index 00000000..c01a1f26 --- /dev/null +++ b/examples/test/semanticTests/events_event_lots_of_data/event_lots_of_data_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_no_arguments/event_no_arguments.sol b/examples/test/semanticTests/events_event_no_arguments/event_no_arguments.sol new file mode 100644 index 00000000..235afeb6 --- /dev/null +++ b/examples/test/semanticTests/events_event_no_arguments/event_no_arguments.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(); + function deposit() public { + emit Deposit(); + } +} +// ---- +// deposit() -> +// ~ emit Deposit() diff --git a/examples/test/semanticTests/events_event_no_arguments/event_no_arguments_standard_input.json b/examples/test/semanticTests/events_event_no_arguments/event_no_arguments_standard_input.json new file mode 100644 index 00000000..388370ac --- /dev/null +++ b/examples/test/semanticTests/events_event_no_arguments/event_no_arguments_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + }, + "event_constructor.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n constructor() {\n emit Deposit(msg.sender, bytes32(\"abc\"), 7);\n }\n}\n// ----\n// constructor()\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #\"abc\", 0x07\n" + }, + "event_dynamic_array_storage.sol": { + "content": "contract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "event_emit_interface_event_via_library.sol": { + "content": "interface I {\n event E();\n}\n\nlibrary L {\n function f() internal {\n emit I.E();\n }\n}\n\ncontract C {\n function g() public {\n L.f();\n }\n}\n\n// ----\n// g() ->\n// ~ emit E()\n" + }, + "event_anonymous.sol": { + "content": "contract ClientReceipt {\n event Deposit() anonymous;\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit \n" + }, + "event_emit_from_a_foreign_contract_same_name.sol": { + "content": "contract C {\n event E(uint256 value);\n}\n\ncontract D {\n event E(uint256 value);\n\n function test() public {\n emit C.E(1);\n emit E(2);\n }\n}\n\n// ----\n// test() ->\n// ~ emit E(uint256): 0x01\n// ~ emit E(uint256): 0x02\n" + }, + "event_indexed_string.sol": { + "content": "contract C {\n string x;\n uint[4] y;\n event E(string indexed r, uint[4] indexed t);\n function deposit() public {\n for (uint i = 0; i < 90; i++)\n bytes(x).push(0);\n for (uint8 i = 0; i < 90; i++)\n bytes(x)[i] = bytes1(i);\n y[0] = 4;\n y[1] = 5;\n y[2] = 6;\n y[3] = 7;\n emit E(x, y);\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81\n// gas irOptimized: 332788\n// gas legacy: 366022\n// gas legacyOptimized: 362429\n" + }, + "event_no_arguments.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n function deposit() public {\n emit Deposit();\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data.sol b/examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data.sol new file mode 100644 index 00000000..9e9c0806 --- /dev/null +++ b/examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data.sol @@ -0,0 +1,9 @@ +contract ClientReceipt { + event Deposit(uint fixeda, bytes dynx, uint fixedb); + function deposit() public { + emit Deposit(10, msg.data, 15); + } +} +// ---- +// deposit() -> +// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data_standard_input.json b/examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data_standard_input.json new file mode 100644 index 00000000..50d06861 --- /dev/null +++ b/examples/test/semanticTests/events_event_really_lots_of_data/event_really_lots_of_data_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage.sol b/examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage.sol new file mode 100644 index 00000000..1c993113 --- /dev/null +++ b/examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage.sol @@ -0,0 +1,13 @@ +contract ClientReceipt { + bytes x; + event Deposit(uint fixeda, bytes dynx, uint fixedb); + function deposit() public { + x.push("A"); + x.push("B"); + x.push("C"); + emit Deposit(10, x, 15); + } +} +// ---- +// deposit() -> +// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, "ABC" diff --git a/examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage_standard_input.json b/examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage_standard_input.json new file mode 100644 index 00000000..c082d3d7 --- /dev/null +++ b/examples/test/semanticTests/events_event_really_lots_of_data_from_storage/event_really_lots_of_data_from_storage_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage.sol b/examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage.sol new file mode 100644 index 00000000..01fcc456 --- /dev/null +++ b/examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage.sol @@ -0,0 +1,15 @@ +contract ClientReceipt { + bytes x; + event Deposit(uint fixeda, bytes dynx, uint fixedb); + function deposit() public { + x = new bytes(31); + x[0] = "A"; + x[1] = "B"; + x[2] = "C"; + x[30] = "Z"; + emit Deposit(10, x, 15); + } +} +// ---- +// deposit() -> +// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, "ABC\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Z" diff --git a/examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage_standard_input.json b/examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage_standard_input.json new file mode 100644 index 00000000..68775b68 --- /dev/null +++ b/examples/test/semanticTests/events_event_really_really_lots_of_data_from_storage/event_really_really_lots_of_data_from_storage_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_selector/event_selector.sol b/examples/test/semanticTests/events_event_selector/event_selector.sol new file mode 100644 index 00000000..b42ba490 --- /dev/null +++ b/examples/test/semanticTests/events_event_selector/event_selector.sol @@ -0,0 +1,58 @@ +library L { + event E(); +} + +library S { + event E(uint); +} + +library T { + event E(); +} + +interface I { + event E(); +} + +contract B { + event E(); +} + +contract D { + event F(); +} + +contract C is D { + function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) { + assert(L.E.selector == T.E.selector); + assert(I.E.selector == L.E.selector); + assert(T.E.selector == I.E.selector); + assert(B.E.selector == T.E.selector); + + assert(L.E.selector != S.E.selector); + assert(T.E.selector != S.E.selector); + assert(I.E.selector != S.E.selector); + assert(B.E.selector != S.E.selector); + + return (L.E.selector, S.E.selector, I.E.selector, B.E.selector); + } + + bytes32 s1 = L.E.selector; + bytes32 s2 = S.E.selector; + bytes32 s3 = T.E.selector; + bytes32 s4 = I.E.selector; + bytes32 s5 = B.E.selector; + function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) { + return (s1, s2, s3, s4, s5); + } + + function test3() external returns (bytes32) { + return (F.selector); + } +} +// ==== +// compileViaYul: also +// ---- +// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 +// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 +// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a diff --git a/examples/test/semanticTests/events_event_selector/event_selector_standard_input.json b/examples/test/semanticTests/events_event_selector/event_selector_standard_input.json new file mode 100644 index 00000000..a0b5584e --- /dev/null +++ b/examples/test/semanticTests/events_event_selector/event_selector_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level.sol b/examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level.sol new file mode 100644 index 00000000..8c5b6c95 --- /dev/null +++ b/examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level.sol @@ -0,0 +1,15 @@ +event E(); + +library L { + event E(); +} + +contract C { + function main() external pure returns (bytes32, bytes32) { + assert(E.selector == L.E.selector); + + return (E.selector, L.E.selector); + } +} +// ---- +// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 diff --git a/examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level_standard_input.json b/examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level_standard_input.json new file mode 100644 index 00000000..c7c878db --- /dev/null +++ b/examples/test/semanticTests/events_event_selector_file_level/event_selector_file_level_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level.sol b/examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level.sol new file mode 100644 index 00000000..01c7d85a --- /dev/null +++ b/examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level.sol @@ -0,0 +1,38 @@ +event E(); + +library L1 { + event E(string); +} + +library L2 { + event E(); +} + +library K { + function main() internal pure returns (bytes32, bytes32, bytes32) { + // Here E is the global event. + assert(E.selector != L1.E.selector); + assert(E.selector == L2.E.selector); + + return (E.selector, L1.E.selector, L2.E.selector); + } +} + +contract C { + event E(string); + + function main() external pure returns (bytes32, bytes32, bytes32) { + // Here E is the local event. + assert(E.selector == L1.E.selector); + assert(E.selector != L2.E.selector); + + return (E.selector, L1.E.selector, L2.E.selector); + } + + function k_main() external pure returns (bytes32, bytes32, bytes32) { + return K.main(); + } +} +// ---- +// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 +// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028 diff --git a/examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level_standard_input.json b/examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level_standard_input.json new file mode 100644 index 00000000..0d31d8d7 --- /dev/null +++ b/examples/test/semanticTests/events_event_shadowing_file_level/event_shadowing_file_level_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library.sol b/examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library.sol new file mode 100644 index 00000000..d8dc0f15 --- /dev/null +++ b/examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; +library L { + struct S { + uint8 a; + int16 b; + } + event E(S indexed, S); + function f() internal { + S memory s; + emit E(s, s); + } +} +contract C { + constructor() { + L.f(); + } +} +// ---- +// constructor() +// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00 +// gas legacy: 150602 diff --git a/examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library_standard_input.json b/examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library_standard_input.json new file mode 100644 index 00000000..705491af --- /dev/null +++ b/examples/test/semanticTests/events_event_signature_in_library/event_signature_in_library_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array.sol b/examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array.sol new file mode 100644 index 00000000..a72ad938 --- /dev/null +++ b/examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array.sol @@ -0,0 +1,11 @@ +contract C { + event E(uint[], uint[1]); + + // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug. + function f(uint[] memory a, uint[1] calldata b) public { + emit E(a, b); + } +} +// ---- +// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff -> +// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff diff --git a/examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array_standard_input.json b/examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array_standard_input.json new file mode 100644 index 00000000..7d571df9 --- /dev/null +++ b/examples/test/semanticTests/events_event_static_calldata_uint_array_and_dynamic_array/event_static_calldata_uint_array_and_dynamic_array_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_string/event_string.sol b/examples/test/semanticTests/events_event_string/event_string.sol new file mode 100644 index 00000000..b2998887 --- /dev/null +++ b/examples/test/semanticTests/events_event_string/event_string.sol @@ -0,0 +1,9 @@ +contract C { + event E(string r); + function deposit() public { + emit E("HELLO WORLD"); + } +} +// ---- +// deposit() -> +// ~ emit E(string): 0x20, 0x0b, "HELLO WORLD" diff --git a/examples/test/semanticTests/events_event_string/event_string_standard_input.json b/examples/test/semanticTests/events_event_string/event_string_standard_input.json new file mode 100644 index 00000000..07a534b5 --- /dev/null +++ b/examples/test/semanticTests/events_event_string/event_string_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2.sol b/examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2.sol new file mode 100644 index 00000000..a77c3150 --- /dev/null +++ b/examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; +contract C { + struct S { uint a; } + event E(S); + function createEvent(uint x) public { + emit E(S(x)); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E((uint256)): 0x2a diff --git a/examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2_standard_input.json b/examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2_standard_input.json new file mode 100644 index 00000000..8e5347f2 --- /dev/null +++ b/examples/test/semanticTests/events_event_struct_memory_v2/event_struct_memory_v2_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2.sol b/examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2.sol new file mode 100644 index 00000000..b64d8cff --- /dev/null +++ b/examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2.sol @@ -0,0 +1,13 @@ +pragma abicoder v2; +contract C { + struct S { uint a; } + event E(S); + S s; + function createEvent(uint x) public { + s.a = x; + emit E(s); + } +} +// ---- +// createEvent(uint256): 42 -> +// ~ emit E((uint256)): 0x2a diff --git a/examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2_standard_input.json b/examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2_standard_input.json new file mode 100644 index 00000000..4799ac27 --- /dev/null +++ b/examples/test/semanticTests/events_event_struct_storage_v2/event_struct_storage_v2_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_events_with_same_name/events_with_same_name.sol b/examples/test/semanticTests/events_events_with_same_name/events_with_same_name.sol new file mode 100644 index 00000000..22a0895f --- /dev/null +++ b/examples/test/semanticTests/events_events_with_same_name/events_with_same_name.sol @@ -0,0 +1,31 @@ +contract ClientReceipt { + event Deposit(); + event Deposit(address _addr); + event Deposit(address _addr, uint _amount); + event Deposit(address _addr, bool _flag); + function deposit() public returns (uint) { + emit Deposit(); + return 1; + } + function deposit(address _addr) public returns (uint) { + emit Deposit(_addr); + return 2; + } + function deposit(address _addr, uint _amount) public returns (uint) { + emit Deposit(_addr, _amount); + return 3; + } + function deposit(address _addr, bool _flag) public returns (uint) { + emit Deposit(_addr, _flag); + return 4; + } +} +// ---- +// deposit() -> 1 +// ~ emit Deposit() +// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2 +// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 +// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3 +// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64 +// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4 +// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false diff --git a/examples/test/semanticTests/events_events_with_same_name/events_with_same_name_standard_input.json b/examples/test/semanticTests/events_events_with_same_name/events_with_same_name_standard_input.json new file mode 100644 index 00000000..99c18d9e --- /dev/null +++ b/examples/test/semanticTests/events_events_with_same_name/events_with_same_name_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level.sol b/examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level.sol new file mode 100644 index 00000000..222e0b0c --- /dev/null +++ b/examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level.sol @@ -0,0 +1,32 @@ +event Deposit(); +event Deposit(address _addr); +event Deposit(address _addr, uint _amount); +event Deposit(address _addr, bool _flag); + +contract ClientReceipt { + function deposit() public returns (uint) { + emit Deposit(); + return 1; + } + function deposit(address _addr) public returns (uint) { + emit Deposit(_addr); + return 2; + } + function deposit(address _addr, uint _amount) public returns (uint) { + emit Deposit(_addr, _amount); + return 3; + } + function deposit(address _addr, bool _flag) public returns (uint) { + emit Deposit(_addr, _flag); + return 4; + } +} +// ---- +// deposit() -> 1 +// ~ emit Deposit() +// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2 +// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 +// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3 +// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64 +// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4 +// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false diff --git a/examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level_standard_input.json b/examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level_standard_input.json new file mode 100644 index 00000000..21b3526b --- /dev/null +++ b/examples/test/semanticTests/events_events_with_same_name_file_level/events_with_same_name_file_level_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit.sol b/examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit.sol new file mode 100644 index 00000000..de87fe41 --- /dev/null +++ b/examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit.sol @@ -0,0 +1,30 @@ +contract A { + event Deposit(); +} + +contract B { + event Deposit(address _addr); +} + +contract ClientReceipt is A, B { + event Deposit(address _addr, uint _amount); + function deposit() public returns (uint) { + emit Deposit(); + return 1; + } + function deposit(address _addr) public returns (uint) { + emit Deposit(_addr); + return 1; + } + function deposit(address _addr, uint _amount) public returns (uint) { + emit Deposit(_addr, _amount); + return 1; + } +} +// ---- +// deposit() -> 1 +// ~ emit Deposit() +// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1 +// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 +// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1 +// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64 diff --git a/examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit_standard_input.json b/examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit_standard_input.json new file mode 100644 index 00000000..3c27d492 --- /dev/null +++ b/examples/test/semanticTests/events_events_with_same_name_inherited_emit/events_with_same_name_inherited_emit_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/events_simple/simple.sol b/examples/test/semanticTests/events_simple/simple.sol new file mode 100644 index 00000000..018c91e7 --- /dev/null +++ b/examples/test/semanticTests/events_simple/simple.sol @@ -0,0 +1,17 @@ +contract C { + event E(); +} + +contract Test is C { + event E(uint256, uint256); + function f() public { + emit C.E(); + emit E(1,2); + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> +// ~ emit E() +// ~ emit E(uint256,uint256): 0x01, 0x02 diff --git a/examples/test/semanticTests/events_simple/simple_standard_input.json b/examples/test/semanticTests/events_simple/simple_standard_input.json new file mode 100644 index 00000000..d48ebe91 --- /dev/null +++ b/examples/test/semanticTests/events_simple/simple_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "event_selector_file_level.sol": { + "content": "event E();\n\nlibrary L {\n event E();\n}\n\ncontract C {\n function main() external pure returns (bytes32, bytes32) {\n assert(E.selector == L.E.selector);\n\n return (E.selector, L.E.selector);\n }\n}\n// ----\n// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_emit_via_interface.sol": { + "content": "interface I {\n event Event(address indexed _from, uint256 _value);\n}\n\ncontract C {\n function emitEvent(uint256 _value) public {\n emit I.Event(msg.sender, _value);\n }\n}\n\n// ----\n// emitEvent(uint256): 100 ->\n// ~ emit Event(address,uint256): #0x1212121212121212121212121212120000000012, 0x64\n" + }, + "event_access_through_base_name_emit.sol": { + "content": "contract A {\n event x();\n}\ncontract B is A {\n function f() public returns (uint) {\n emit A.x();\n return 1;\n }\n}\n// ----\n// f() -> 1\n// ~ emit x()\n" + }, + "event_indexed_function2.sol": { + "content": "contract C {\n event TestA(function() external indexed);\n event TestB(function(uint256) external indexed);\n function f1() public {\n emit TestA(this.f1);\n }\n function f2(uint256 a) public {\n emit TestB(this.f2);\n }\n}\n// ----\n// f1() ->\n// ~ emit TestA(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ec27fc3050000000000000000\n// f2(uint256): 1 ->\n// ~ emit TestB(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79ebf3724af0000000000000000\n" + }, + "event_struct_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n function createEvent(uint x) public {\n emit E(S(x));\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_nested_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n uint[][] arr;\n function createEvent(uint x) public {\n arr.push(new uint[](2));\n arr.push(new uint[](2));\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n// gas irOptimized: 185148\n// gas legacy: 187493\n// gas legacyOptimized: 184548\n" + }, + "event_indexed_mixed.sol": { + "content": "contract C {\n // Indexed parameters are always listed first in the output.\n // The data is the ABI encoding of just the non-indexed parameters,\n // so putting the indexed parameters \"in between\" would mess\n // up the offsets for the reader.\n event E(uint a, uint indexed r, uint b, bytes c);\n function deposit() public {\n emit E(1, 2, 3, \"def\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, \"def\"\n// gas irOptimized: 23709\n// gas legacy: 24342\n// gas legacyOptimized: 23753\n" + }, + "event.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id, bool _manually) public payable {\n if (_manually) {\n bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f;\n uint value = msg.value;\n address sender = msg.sender;\n assembly {\n mstore(0, value)\n log3(0, 0x20, s, sender, _id)\n }\n } else {\n emit Deposit(msg.sender, _id, msg.value);\n }\n }\n}\n// ----\n// deposit(bytes32,bool), 18 wei: 0x1234, true ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n// deposit(bytes32,bool), 18 wei: 0x1234, false ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_dynamic_array_memory.sol": { + "content": "contract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_emit_from_other_contract.sol": { + "content": "contract D {\n event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\ncontract C {\n D d;\n constructor() {\n d = new D();\n }\n function deposit(bytes32 _id) public payable {\n d.deposit(_id);\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 113970\n// gas irOptimized code: 51400\n// gas legacy: 119791\n// gas legacy code: 125200\n// gas legacyOptimized: 114187\n// gas legacyOptimized code: 57400\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: #0xc06afe3a8444fc0004668591e8306bfb9968e79e, #0x1234, 0x00\n" + }, + "event_dynamic_nested_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[][]);\n function createEvent(uint x) public {\n uint[][] memory arr = new uint[][](2);\n arr[0] = new uint[](2);\n arr[1] = new uint[](2);\n arr[0][0] = x;\n arr[0][1] = x + 1;\n arr[1][0] = x + 2;\n arr[1][1] = x + 3;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d\n" + }, + "event_indexed_function.sol": { + "content": "contract C {\n event Test(function() external indexed);\n function f() public {\n emit Test(this.f);\n }\n}\n// ----\n// f() ->\n// ~ emit Test(function): #0xc06afe3a8444fc0004668591e8306bfb9968e79e26121ff00000000000000000\n" + }, + "event_struct_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { uint a; }\n event E(S);\n S s;\n function createEvent(uint x) public {\n s.a = x;\n emit E(s);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E((uint256)): 0x2a\n" + }, + "event_dynamic_array_memory_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n function createEvent(uint x) public {\n uint[] memory arr = new uint[](3);\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n" + }, + "event_selector.sol": { + "content": "library L {\n event E();\n}\n\nlibrary S {\n event E(uint);\n}\n\nlibrary T {\n event E();\n}\n\ninterface I {\n event E();\n}\n\ncontract B {\n event E();\n}\n\ncontract D {\n event F();\n}\n\ncontract C is D {\n function test1() external pure returns (bytes32, bytes32, bytes32, bytes32) {\n assert(L.E.selector == T.E.selector);\n assert(I.E.selector == L.E.selector);\n assert(T.E.selector == I.E.selector);\n assert(B.E.selector == T.E.selector);\n\n assert(L.E.selector != S.E.selector);\n assert(T.E.selector != S.E.selector);\n assert(I.E.selector != S.E.selector);\n assert(B.E.selector != S.E.selector);\n\n return (L.E.selector, S.E.selector, I.E.selector, B.E.selector);\n }\n\n bytes32 s1 = L.E.selector;\n bytes32 s2 = S.E.selector;\n bytes32 s3 = T.E.selector;\n bytes32 s4 = I.E.selector;\n bytes32 s5 = B.E.selector;\n function test2() external returns (bytes32, bytes32, bytes32, bytes32, bytes32) {\n return (s1, s2, s3, s4, s5);\n }\n\n function test3() external returns (bytes32) {\n return (F.selector);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// test1() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test2() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x2ff0672f372fbe844b353429d4510ea5e43683af134c54f75f789ff57bc0c0, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// test3() -> 0x28811f5935c16a099486acb976b3a6b4942950a1425a74e9eb3e9b7f7135e12a\n" + }, + "events_with_same_name.sol": { + "content": "contract ClientReceipt {\n event Deposit();\n event Deposit(address _addr);\n event Deposit(address _addr, uint _amount);\n event Deposit(address _addr, bool _flag);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_signature_in_library.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S {\n uint8 a;\n int16 b;\n }\n event E(S indexed, S);\n function f() internal {\n S memory s;\n emit E(s, s);\n }\n}\ncontract C {\n constructor() {\n L.f();\n }\n}\n// ----\n// constructor()\n// ~ emit E((uint8,int16),(uint8,int16)): #0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5, 0x00, 0x00\n// gas legacy: 150602\n" + }, + "event_dynamic_array_storage_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n event E(uint[]);\n uint[] arr;\n function createEvent(uint x) public {\n while (arr.length < 3)\n arr.push();\n arr[0] = x;\n arr[1] = x + 1;\n arr[2] = x + 2;\n emit E(arr);\n }\n}\n// ----\n// createEvent(uint256): 42 ->\n// ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c\n// gas irOptimized: 114231\n// gas legacy: 116313\n// gas legacyOptimized: 114407\n" + }, + "events_with_same_name_file_level.sol": { + "content": "event Deposit();\nevent Deposit(address _addr);\nevent Deposit(address _addr, uint _amount);\nevent Deposit(address _addr, bool _flag);\n\ncontract ClientReceipt {\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 2;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 3;\n }\n function deposit(address _addr, bool _flag) public returns (uint) {\n emit Deposit(_addr, _flag);\n return 4;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4\n// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false\n" + }, + "event_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(address _from, bytes32 _id, uint _value, bool _flag);\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, true);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256,bool): 0x1212121212121212121212121212120000000012, 0x1234, 0x12, true\n" + }, + "event_emit_file_level.sol": { + "content": "event Deposit(address indexed _from, bytes32 indexed _id, uint _value);\n\ncontract ClientReceipt {\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value);\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12\n" + }, + "event_emit_from_a_foreign_contract.sol": { + "content": "contract C {\n event E();\n}\n\ncontract D {\n function test() public {\n emit C.E();\n }\n}\n\n// ----\n// test() ->\n// ~ emit E()\n" + }, + "event_really_lots_of_data.sol": { + "content": "contract ClientReceipt {\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n emit Deposit(10, msg.data, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x04, 0xd0e30db000000000000000000000000000000000000000000000000000000000\n" + }, + "event_anonymous_with_topics.sol": { + "content": "contract ClientReceipt {\n event Deposit(address indexed _from, bytes32 indexed _id, uint indexed _value, uint indexed _value2, bytes32 data) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(msg.sender, _id, msg.value, 2, \"abc\");\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit : #0x1212121212121212121212121212120000000012, #0x1234, #0x12, #0x02, \"abc\"\n" + }, + "event_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x.push(\"A\");\n x.push(\"B\");\n x.push(\"C\");\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x03, \"ABC\"\n" + }, + "events_with_same_name_inherited_emit.sol": { + "content": "contract A {\n event Deposit();\n}\n\ncontract B {\n event Deposit(address _addr);\n}\n\ncontract ClientReceipt is A, B {\n event Deposit(address _addr, uint _amount);\n function deposit() public returns (uint) {\n emit Deposit();\n return 1;\n }\n function deposit(address _addr) public returns (uint) {\n emit Deposit(_addr);\n return 1;\n }\n function deposit(address _addr, uint _amount) public returns (uint) {\n emit Deposit(_addr, _amount);\n return 1;\n }\n}\n// ----\n// deposit() -> 1\n// ~ emit Deposit()\n// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 1\n// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988\n// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 1\n// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64\n" + }, + "event_anonymous_with_signature_collision2.sol": { + "content": "contract ClientReceipt {\n event Withdraw(uint _value, string owner);\n event Deposit(uint256 indexed _from, bytes32 indexed _id, uint _value) anonymous;\n function deposit(bytes32 _id) public payable {\n emit Deposit(0x5ddaa77ac5bda319ba947e31bee594711f39ed1b20d079d438dbad5ed729fb30, _id, msg.value); // 0x5ddaa77a -> 'Withdraw(uint256,string)'\n }\n}\n// ----\n// deposit(bytes32), 18 wei: 0x1234 ->\n// ~ emit Withdraw(uint256,string): #0x1234, 0x12\n" + }, + "event_shadowing_file_level.sol": { + "content": "event E();\n\nlibrary L1 {\n event E(string);\n}\n\nlibrary L2 {\n event E();\n}\n\nlibrary K {\n function main() internal pure returns (bytes32, bytes32, bytes32) {\n // Here E is the global event.\n assert(E.selector != L1.E.selector);\n assert(E.selector == L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n}\n\ncontract C {\n event E(string);\n\n function main() external pure returns (bytes32, bytes32, bytes32) {\n // Here E is the local event.\n assert(E.selector == L1.E.selector);\n assert(E.selector != L2.E.selector);\n\n return (E.selector, L1.E.selector, L2.E.selector);\n }\n\n function k_main() external pure returns (bytes32, bytes32, bytes32) {\n return K.main();\n }\n}\n// ----\n// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028\n" + }, + "event_string.sol": { + "content": "contract C {\n event E(string r);\n function deposit() public {\n emit E(\"HELLO WORLD\");\n }\n}\n// ----\n// deposit() ->\n// ~ emit E(string): 0x20, 0x0b, \"HELLO WORLD\"\n" + }, + "event_static_calldata_uint_array_and_dynamic_array.sol": { + "content": "contract C {\n event E(uint[], uint[1]);\n\n // This case used to be affected by the buggy cleanup due to ABIEncoderV2HeadOverflowWithStaticArrayCleanup bug.\n function f(uint[] memory a, uint[1] calldata b) public {\n emit E(a, b);\n }\n}\n// ----\n// f(uint256[],uint256[1]): 0x40, 0xff, 1, 0xffff ->\n// ~ emit E(uint256[],uint256[1]): 0x40, 0xff, 0x01, 0xffff\n" + }, + "event_really_really_lots_of_data_from_storage.sol": { + "content": "contract ClientReceipt {\n bytes x;\n event Deposit(uint fixeda, bytes dynx, uint fixedb);\n function deposit() public {\n x = new bytes(31);\n x[0] = \"A\";\n x[1] = \"B\";\n x[2] = \"C\";\n x[30] = \"Z\";\n emit Deposit(10, x, 15);\n }\n}\n// ----\n// deposit() ->\n// ~ emit Deposit(uint256,bytes,uint256): 0x0a, 0x60, 0x0f, 0x1f, \"ABC\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0Z\"\n" + }, + "simple.sol": { + "content": "contract C {\n event E();\n}\n\ncontract Test is C {\n event E(uint256, uint256);\n function f() public {\n emit C.E();\n emit E(1,2);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() ->\n// ~ emit E()\n// ~ emit E(uint256,uint256): 0x01, 0x02\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/experimental_stub/stub.sol b/examples/test/semanticTests/experimental_stub/stub.sol new file mode 100644 index 00000000..6e7a750f --- /dev/null +++ b/examples/test/semanticTests/experimental_stub/stub.sol @@ -0,0 +1,97 @@ +pragma experimental solidity; + +type word = __builtin("word"); +type bool = __builtin("bool"); +type integer = __builtin("integer"); + +type uint256 = word; + +instantiation uint256: + { + function add(x, y) -> uint256 { + let a = uint256.rep(x); + let b = uint256.rep(y); + assembly { + a := add(a,b) + } + return uint256.abs(a); + } +} + + +instantiation uint256: * { + function mul(x, y) -> uint256 { + let a = uint256.rep(x); + let b = uint256.rep(y); + assembly { + a := mul(a,b) + } + return uint256.abs(a); + } +} +instantiation word: * { + function mul(x, y) -> word { + let z: word; + assembly { + z := mul(x,y) + } + return z; + } +} + +instantiation word: Integer { + function fromInteger(x:integer) -> word { + //x + x; + } +} + +instantiation word: == { + function eq(x, y) -> bool { + assembly { + x := eq(x, y) + } + } +} + + +function f(x:uint256->uint256,y:uint256) -> uint256 +{ + return x(y); +} + +function g(x:uint256) -> uint256 +{ + return x; +} + +contract C { + fallback() external { + let arg; + assembly { + arg := calldataload(0) + } + let x : word; + if (bool.abs(arg)) { + assembly { + x := 0x10 + } + } + let w = uint256.abs(x); +// w = f(g, w); + w = w * w + w; + let y : word; + let z : (uint256,uint256); + assembly { y := 2 } + y = uint256.rep(w) * y; + assembly { + mstore(0, y) + return(0, 32) + } + } +} +// ==== +// EVMVersion: >=constantinople +// ==== +// compileViaYul: true +// ---- +// (): 0 -> 0 +// (): 1 -> 544 diff --git a/examples/test/semanticTests/experimental_stub/stub_standard_input.json b/examples/test/semanticTests/experimental_stub/stub_standard_input.json new file mode 100644 index 00000000..23f0f738 --- /dev/null +++ b/examples/test/semanticTests/experimental_stub/stub_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "type_class.sol": { + "content": "pragma experimental solidity;\n\ntype word = __builtin(\"word\");\ntype bool = __builtin(\"bool\");\n\ntype Cat = word;\ntype Dog = word;\n\nclass Self: Animal {\n function new() -> Self;\n function alive(self: Self) -> bool;\n}\n\ninstantiation Cat: Animal {\n function new() -> Cat {\n let c;\n return c;\n }\n\n function alive(self: Cat) -> bool {\n // TODO: Boolean literals or operators not implemented.\n let w;\n assembly {\n w := 1\n }\n return bool.abs(w);\n }\n}\n\ninstantiation Dog: Animal {\n function new() -> Dog {\n let d: Dog;\n return d;\n }\n\n function alive(self: Dog) -> bool {\n let b: bool;\n return b;\n }\n}\n\ncontract C {\n fallback() external {\n let boolResult1: bool;\n let boolResult2: bool;\n\n let c: Cat = Animal.new();\n boolResult1 = Animal.alive(c);\n\n let d: Dog = Animal.new();\n boolResult2 = Animal.alive(d);\n\n let wordResult1 = bool.rep(boolResult1);\n let wordResult2 = bool.rep(boolResult2);\n assembly {\n mstore(0, wordResult1)\n mstore(32, wordResult2)\n return(0, 64)\n }\n }\n}\n\n// ====\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// () -> 1, 0\n" + }, + "stub.sol": { + "content": "pragma experimental solidity;\n\ntype word = __builtin(\"word\");\ntype bool = __builtin(\"bool\");\ntype integer = __builtin(\"integer\");\n\ntype uint256 = word;\n\ninstantiation uint256: + {\n function add(x, y) -> uint256 {\n let a = uint256.rep(x);\n let b = uint256.rep(y);\n assembly {\n a := add(a,b)\n }\n return uint256.abs(a);\n }\n}\n\n\ninstantiation uint256: * {\n function mul(x, y) -> uint256 {\n let a = uint256.rep(x);\n let b = uint256.rep(y);\n assembly {\n a := mul(a,b)\n }\n return uint256.abs(a);\n }\n}\ninstantiation word: * {\n function mul(x, y) -> word {\n let z: word;\n assembly {\n z := mul(x,y)\n }\n return z;\n }\n}\n\ninstantiation word: Integer {\n function fromInteger(x:integer) -> word {\n //x + x;\n }\n}\n\ninstantiation word: == {\n function eq(x, y) -> bool {\n assembly {\n x := eq(x, y)\n }\n }\n}\n\n\nfunction f(x:uint256->uint256,y:uint256) -> uint256\n{\n return x(y);\n}\n\nfunction g(x:uint256) -> uint256\n{\n return x;\n}\n\ncontract C {\n fallback() external {\n let arg;\n assembly {\n arg := calldataload(0)\n }\n let x : word;\n if (bool.abs(arg)) {\n assembly {\n x := 0x10\n }\n }\n let w = uint256.abs(x);\n// w = f(g, w);\n w = w * w + w;\n let y : word;\n let z : (uint256,uint256);\n assembly { y := 2 }\n y = uint256.rep(w) * y;\n assembly {\n mstore(0, y)\n return(0, 32)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ====\n// compileViaYul: true\n// ----\n// (): 0 -> 0\n// (): 1 -> 544\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/experimental_type_class/type_class.sol b/examples/test/semanticTests/experimental_type_class/type_class.sol new file mode 100644 index 00000000..69fa568d --- /dev/null +++ b/examples/test/semanticTests/experimental_type_class/type_class.sol @@ -0,0 +1,67 @@ +pragma experimental solidity; + +type word = __builtin("word"); +type bool = __builtin("bool"); + +type Cat = word; +type Dog = word; + +class Self: Animal { + function new() -> Self; + function alive(self: Self) -> bool; +} + +instantiation Cat: Animal { + function new() -> Cat { + let c; + return c; + } + + function alive(self: Cat) -> bool { + // TODO: Boolean literals or operators not implemented. + let w; + assembly { + w := 1 + } + return bool.abs(w); + } +} + +instantiation Dog: Animal { + function new() -> Dog { + let d: Dog; + return d; + } + + function alive(self: Dog) -> bool { + let b: bool; + return b; + } +} + +contract C { + fallback() external { + let boolResult1: bool; + let boolResult2: bool; + + let c: Cat = Animal.new(); + boolResult1 = Animal.alive(c); + + let d: Dog = Animal.new(); + boolResult2 = Animal.alive(d); + + let wordResult1 = bool.rep(boolResult1); + let wordResult2 = bool.rep(boolResult2); + assembly { + mstore(0, wordResult1) + mstore(32, wordResult2) + return(0, 64) + } + } +} + +// ==== +// EVMVersion: >=constantinople +// compileViaYul: true +// ---- +// () -> 1, 0 diff --git a/examples/test/semanticTests/experimental_type_class/type_class_standard_input.json b/examples/test/semanticTests/experimental_type_class/type_class_standard_input.json new file mode 100644 index 00000000..2a23e7f2 --- /dev/null +++ b/examples/test/semanticTests/experimental_type_class/type_class_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "type_class.sol": { + "content": "pragma experimental solidity;\n\ntype word = __builtin(\"word\");\ntype bool = __builtin(\"bool\");\n\ntype Cat = word;\ntype Dog = word;\n\nclass Self: Animal {\n function new() -> Self;\n function alive(self: Self) -> bool;\n}\n\ninstantiation Cat: Animal {\n function new() -> Cat {\n let c;\n return c;\n }\n\n function alive(self: Cat) -> bool {\n // TODO: Boolean literals or operators not implemented.\n let w;\n assembly {\n w := 1\n }\n return bool.abs(w);\n }\n}\n\ninstantiation Dog: Animal {\n function new() -> Dog {\n let d: Dog;\n return d;\n }\n\n function alive(self: Dog) -> bool {\n let b: bool;\n return b;\n }\n}\n\ncontract C {\n fallback() external {\n let boolResult1: bool;\n let boolResult2: bool;\n\n let c: Cat = Animal.new();\n boolResult1 = Animal.alive(c);\n\n let d: Dog = Animal.new();\n boolResult2 = Animal.alive(d);\n\n let wordResult1 = bool.rep(boolResult1);\n let wordResult2 = bool.rep(boolResult2);\n assembly {\n mstore(0, wordResult1)\n mstore(32, wordResult2)\n return(0, 64)\n }\n }\n}\n\n// ====\n// EVMVersion: >=constantinople\n// compileViaYul: true\n// ----\n// () -> 1, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/exponentiation_literal_base/literal_base.sol b/examples/test/semanticTests/exponentiation_literal_base/literal_base.sol new file mode 100644 index 00000000..3dcba494 --- /dev/null +++ b/examples/test/semanticTests/exponentiation_literal_base/literal_base.sol @@ -0,0 +1,18 @@ +contract test { + function f(uint x) public pure returns (uint, int) { + unchecked { + uint a = 2 ** x; + int b = -2 ** x; + return (a, b); + } + } +} +// ---- +// f(uint256): 0 -> 1, 1 +// f(uint256): 1 -> 2, -2 +// f(uint256): 2 -> 4, 4 +// f(uint256): 13 -> 0x2000, -8192 +// f(uint256): 113 -> 0x020000000000000000000000000000, -10384593717069655257060992658440192 +// f(uint256): 114 -> 0x040000000000000000000000000000, 20769187434139310514121985316880384 +// f(uint256): 1113 -> 0x00, 0 +// f(uint256): 1114 -> 0x00, 0 diff --git a/examples/test/semanticTests/exponentiation_literal_base/literal_base_standard_input.json b/examples/test/semanticTests/exponentiation_literal_base/literal_base_standard_input.json new file mode 100644 index 00000000..959dec99 --- /dev/null +++ b/examples/test/semanticTests/exponentiation_literal_base/literal_base_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "literal_base.sol": { + "content": "contract test {\n function f(uint x) public pure returns (uint, int) {\n unchecked {\n uint a = 2 ** x;\n int b = -2 ** x;\n return (a, b);\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1, 1\n// f(uint256): 1 -> 2, -2\n// f(uint256): 2 -> 4, 4\n// f(uint256): 13 -> 0x2000, -8192\n// f(uint256): 113 -> 0x020000000000000000000000000000, -10384593717069655257060992658440192\n// f(uint256): 114 -> 0x040000000000000000000000000000, 20769187434139310514121985316880384\n// f(uint256): 1113 -> 0x00, 0\n// f(uint256): 1114 -> 0x00, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/exponentiation_signed_base/signed_base.sol b/examples/test/semanticTests/exponentiation_signed_base/signed_base.sol new file mode 100644 index 00000000..f58c0812 --- /dev/null +++ b/examples/test/semanticTests/exponentiation_signed_base/signed_base.sol @@ -0,0 +1,14 @@ +contract test { + function f() public pure returns (int, int) { + int32 x = -3; + uint8 y1; + uint8 y2; + assembly { + y1 := 0x102 + y2 := 0x103 + } + return (x**y1, x**y2); + } +} +// ---- +// f() -> 9, -27 diff --git a/examples/test/semanticTests/exponentiation_signed_base/signed_base_standard_input.json b/examples/test/semanticTests/exponentiation_signed_base/signed_base_standard_input.json new file mode 100644 index 00000000..1c37918e --- /dev/null +++ b/examples/test/semanticTests/exponentiation_signed_base/signed_base_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "literal_base.sol": { + "content": "contract test {\n function f(uint x) public pure returns (uint, int) {\n unchecked {\n uint a = 2 ** x;\n int b = -2 ** x;\n return (a, b);\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1, 1\n// f(uint256): 1 -> 2, -2\n// f(uint256): 2 -> 4, 4\n// f(uint256): 13 -> 0x2000, -8192\n// f(uint256): 113 -> 0x020000000000000000000000000000, -10384593717069655257060992658440192\n// f(uint256): 114 -> 0x040000000000000000000000000000, 20769187434139310514121985316880384\n// f(uint256): 1113 -> 0x00, 0\n// f(uint256): 1114 -> 0x00, 0\n" + }, + "small_exp.sol": { + "content": "contract test {\n function f() public pure returns (uint r) {\n uint32 x;\n uint8 y;\n assembly {\n x := 0xfffffffffe\n y := 0x102\n }\n unchecked { r = x**y; }\n return r;\n }\n}\n// ----\n// f() -> 4\n" + }, + "signed_base.sol": { + "content": "contract test {\n function f() public pure returns (int, int) {\n int32 x = -3;\n uint8 y1;\n uint8 y2;\n assembly {\n y1 := 0x102\n y2 := 0x103\n }\n return (x**y1, x**y2);\n }\n}\n// ----\n// f() -> 9, -27\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/exponentiation_small_exp/small_exp.sol b/examples/test/semanticTests/exponentiation_small_exp/small_exp.sol new file mode 100644 index 00000000..a26675fb --- /dev/null +++ b/examples/test/semanticTests/exponentiation_small_exp/small_exp.sol @@ -0,0 +1,14 @@ +contract test { + function f() public pure returns (uint r) { + uint32 x; + uint8 y; + assembly { + x := 0xfffffffffe + y := 0x102 + } + unchecked { r = x**y; } + return r; + } +} +// ---- +// f() -> 4 diff --git a/examples/test/semanticTests/exponentiation_small_exp/small_exp_standard_input.json b/examples/test/semanticTests/exponentiation_small_exp/small_exp_standard_input.json new file mode 100644 index 00000000..78f7cbcf --- /dev/null +++ b/examples/test/semanticTests/exponentiation_small_exp/small_exp_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "literal_base.sol": { + "content": "contract test {\n function f(uint x) public pure returns (uint, int) {\n unchecked {\n uint a = 2 ** x;\n int b = -2 ** x;\n return (a, b);\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1, 1\n// f(uint256): 1 -> 2, -2\n// f(uint256): 2 -> 4, 4\n// f(uint256): 13 -> 0x2000, -8192\n// f(uint256): 113 -> 0x020000000000000000000000000000, -10384593717069655257060992658440192\n// f(uint256): 114 -> 0x040000000000000000000000000000, 20769187434139310514121985316880384\n// f(uint256): 1113 -> 0x00, 0\n// f(uint256): 1114 -> 0x00, 0\n" + }, + "small_exp.sol": { + "content": "contract test {\n function f() public pure returns (uint r) {\n uint32 x;\n uint8 y;\n assembly {\n x := 0xfffffffffe\n y := 0x102\n }\n unchecked { r = x**y; }\n return r;\n }\n}\n// ----\n// f() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_bit_operators/bit_operators.sol b/examples/test/semanticTests/expressions_bit_operators/bit_operators.sol new file mode 100644 index 00000000..35887059 --- /dev/null +++ b/examples/test/semanticTests/expressions_bit_operators/bit_operators.sol @@ -0,0 +1,17 @@ +contract test { + uint8 x; + uint v; + function f() public returns (uint x, uint y, uint z) { + uint16 a; + uint32 b; + assembly { + a := 0x0f0f0f0f0f + b := 0xff0fff0fff + } + x = a & b; + y = a | b; + z = a ^ b; + } +} +// ---- +// f() -> 3855, 268374015, 268370160 diff --git a/examples/test/semanticTests/expressions_bit_operators/bit_operators_standard_input.json b/examples/test/semanticTests/expressions_bit_operators/bit_operators_standard_input.json new file mode 100644 index 00000000..a5d040ca --- /dev/null +++ b/examples/test/semanticTests/expressions_bit_operators/bit_operators_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison.sol b/examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison.sol new file mode 100644 index 00000000..b1220c51 --- /dev/null +++ b/examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison.sol @@ -0,0 +1,10 @@ +contract test { + function f() public returns (bool) { + bytes2 a = "a"; + bytes2 x = "aa"; + bytes2 b = "b"; + return a < x && x < b; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison_standard_input.json b/examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison_standard_input.json new file mode 100644 index 00000000..943fb4c0 --- /dev/null +++ b/examples/test/semanticTests/expressions_bytes_comparison/bytes_comparison_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types.sol b/examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types.sol new file mode 100644 index 00000000..df07364b --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types.sol @@ -0,0 +1,10 @@ +contract test { + function f(bool cond) public returns (uint) { + uint8 x = 0xcd; + uint16 y = 0xabab; + return cond ? x : y; + } +} +// ---- +// f(bool): true -> 0xcd +// f(bool): false -> 0xabab diff --git a/examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types_standard_input.json new file mode 100644 index 00000000..20a1f65c --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_different_types/conditional_expression_different_types_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_storage_memory_1.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n bytes2[2] memory x;\n x[0] = \"aa\";\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n data1 = cond ? x : y;\n\n uint ret = 0;\n if (data1[0] == \"aa\")\n {\n ret = 1;\n }\n\n if (data1[0] == \"bb\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "conditional_expression_different_types.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint) {\n uint8 x = 0xcd;\n uint16 y = 0xabab;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0xcd\n// f(bool): false -> 0xabab\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal.sol b/examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal.sol new file mode 100644 index 00000000..3915c7b8 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal.sol @@ -0,0 +1,7 @@ +contract test { + function f() public returns(uint d) { + return false ? 5 : 10; + } +} +// ---- +// f() -> 10 diff --git a/examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal_standard_input.json new file mode 100644 index 00000000..e7aabfac --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_false_literal/conditional_expression_false_literal_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_storage_memory_1.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n bytes2[2] memory x;\n x[0] = \"aa\";\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n data1 = cond ? x : y;\n\n uint ret = 0;\n if (data1[0] == \"aa\")\n {\n ret = 1;\n }\n\n if (data1[0] == \"bb\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "conditional_expression_different_types.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint) {\n uint8 x = 0xcd;\n uint16 y = 0xabab;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0xcd\n// f(bool): false -> 0xabab\n" + }, + "tuple_from_ternary_expression.sol": { + "content": "contract C {\n function f() public pure returns (bool){\n bool flag;\n ((flag = true) ? (1, 2, 3) : (3, 2, 1));\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_with_return_values.sol": { + "content": "contract test {\n function f(bool cond, uint v) public returns (uint a, uint b) {\n cond ? a = v : b = v;\n }\n}\n// ----\n// f(bool,uint256): true, 20 -> 20, 0\n// f(bool,uint256): false, 20 -> 0, 20\n" + }, + "conditional_expression_false_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return false ? 5 : 10;\n }\n}\n// ----\n// f() -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions.sol b/examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions.sol new file mode 100644 index 00000000..bff9122b --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions.sol @@ -0,0 +1,12 @@ +contract test { + function x() public returns (uint) { return 1; } + function y() public returns (uint) { return 2; } + + function f(bool cond) public returns (uint) { + function () returns (uint) z = cond ? x : y; + return z(); + } +} +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions_standard_input.json new file mode 100644 index 00000000..ea34d97b --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_functions/conditional_expression_functions_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple.sol b/examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple.sol new file mode 100644 index 00000000..2a9d6de8 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple.sol @@ -0,0 +1,13 @@ +contract test { + function f(uint x) public returns(uint d) { + return x > 100 ? + x > 1000 ? 1000 : 100 + : + x > 50 ? 50 : 10; + } +} +// ---- +// f(uint256): 1001 -> 1000 +// f(uint256): 500 -> 100 +// f(uint256): 80 -> 50 +// f(uint256): 40 -> 10 diff --git a/examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple_standard_input.json new file mode 100644 index 00000000..6940d3e6 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_multiple/conditional_expression_multiple_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1.sol b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1.sol new file mode 100644 index 00000000..3434cca0 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1.sol @@ -0,0 +1,27 @@ +contract test { + bytes2[2] data1; + function f(bool cond) public returns (uint) { + bytes2[2] memory x; + x[0] = "aa"; + bytes2[2] memory y; + y[0] = "bb"; + + data1 = cond ? x : y; + + uint ret = 0; + if (data1[0] == "aa") + { + ret = 1; + } + + if (data1[0] == "bb") + { + ret = 2; + } + + return ret; + } +} +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1_standard_input.json new file mode 100644 index 00000000..05fb89a9 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_1/conditional_expression_storage_memory_1_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_storage_memory_1.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n bytes2[2] memory x;\n x[0] = \"aa\";\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n data1 = cond ? x : y;\n\n uint ret = 0;\n if (data1[0] == \"aa\")\n {\n ret = 1;\n }\n\n if (data1[0] == \"bb\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2.sol b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2.sol new file mode 100644 index 00000000..8633d2bf --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2.sol @@ -0,0 +1,28 @@ +contract test { + bytes2[2] data1; + function f(bool cond) public returns (uint) { + data1[0] = "cc"; + + bytes2[2] memory x; + bytes2[2] memory y; + y[0] = "bb"; + + x = cond ? y : data1; + + uint ret = 0; + if (x[0] == "bb") + { + ret = 1; + } + + if (x[0] == "cc") + { + ret = 2; + } + + return ret; + } +} +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2_standard_input.json new file mode 100644 index 00000000..79e86815 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_storage_memory_2/conditional_expression_storage_memory_2_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal.sol b/examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal.sol new file mode 100644 index 00000000..06247f0d --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal.sol @@ -0,0 +1,7 @@ +contract test { + function f() public returns(uint d) { + return true ? 5 : 10; + } +} +// ---- +// f() -> 5 diff --git a/examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal_standard_input.json new file mode 100644 index 00000000..e2f5ec81 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_true_literal/conditional_expression_true_literal_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples.sol b/examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples.sol new file mode 100644 index 00000000..d27d06ba --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples.sol @@ -0,0 +1,8 @@ +contract test { + function f(bool cond) public returns (uint, uint) { + return cond ? (1, 2) : (3, 4); + } +} +// ---- +// f(bool): true -> 1, 2 +// f(bool): false -> 3, 4 diff --git a/examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples_standard_input.json new file mode 100644 index 00000000..97518544 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_tuples/conditional_expression_tuples_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values.sol b/examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values.sol new file mode 100644 index 00000000..bbaf051b --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values.sol @@ -0,0 +1,8 @@ +contract test { + function f(bool cond, uint v) public returns (uint a, uint b) { + cond ? a = v : b = v; + } +} +// ---- +// f(bool,uint256): true, 20 -> 20, 0 +// f(bool,uint256): false, 20 -> 0, 20 diff --git a/examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values_standard_input.json b/examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values_standard_input.json new file mode 100644 index 00000000..3fe0bae8 --- /dev/null +++ b/examples/test/semanticTests/expressions_conditional_expression_with_return_values/conditional_expression_with_return_values_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_storage_memory_1.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n bytes2[2] memory x;\n x[0] = \"aa\";\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n data1 = cond ? x : y;\n\n uint ret = 0;\n if (data1[0] == \"aa\")\n {\n ret = 1;\n }\n\n if (data1[0] == \"bb\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "conditional_expression_different_types.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint) {\n uint8 x = 0xcd;\n uint16 y = 0xabab;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0xcd\n// f(bool): false -> 0xabab\n" + }, + "tuple_from_ternary_expression.sol": { + "content": "contract C {\n function f() public pure returns (bool){\n bool flag;\n ((flag = true) ? (1, 2, 3) : (3, 2, 1));\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_with_return_values.sol": { + "content": "contract test {\n function f(bool cond, uint v) public returns (uint a, uint b) {\n cond ? a = v : b = v;\n }\n}\n// ----\n// f(bool,uint256): true, 20 -> 20, 0\n// f(bool,uint256): false, 20 -> 0, 20\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const.sol b/examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const.sol new file mode 100644 index 00000000..e2a7ccc7 --- /dev/null +++ b/examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const.sol @@ -0,0 +1,5 @@ +contract test { + function f() public returns(uint d) { return 2 ** 3; } +} +// ---- +// f() -> 8 diff --git a/examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const_standard_input.json b/examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const_standard_input.json new file mode 100644 index 00000000..824273c9 --- /dev/null +++ b/examples/test/semanticTests/expressions_exp_operator_const/exp_operator_const_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed.sol b/examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed.sol new file mode 100644 index 00000000..b2dd001b --- /dev/null +++ b/examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed.sol @@ -0,0 +1,5 @@ +contract test { + function f() public returns(int d) { return (-2) ** 3; } +} +// ---- +// f() -> -8 diff --git a/examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed_standard_input.json b/examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed_standard_input.json new file mode 100644 index 00000000..1f0605ef --- /dev/null +++ b/examples/test/semanticTests/expressions_exp_operator_const_signed/exp_operator_const_signed_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_storage_memory_1.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n bytes2[2] memory x;\n x[0] = \"aa\";\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n data1 = cond ? x : y;\n\n uint ret = 0;\n if (data1[0] == \"aa\")\n {\n ret = 1;\n }\n\n if (data1[0] == \"bb\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "conditional_expression_different_types.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint) {\n uint8 x = 0xcd;\n uint16 y = 0xabab;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0xcd\n// f(bool): false -> 0xabab\n" + }, + "tuple_from_ternary_expression.sol": { + "content": "contract C {\n function f() public pure returns (bool){\n bool flag;\n ((flag = true) ? (1, 2, 3) : (3, 2, 1));\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_with_return_values.sol": { + "content": "contract test {\n function f(bool cond, uint v) public returns (uint a, uint b) {\n cond ? a = v : b = v;\n }\n}\n// ----\n// f(bool,uint256): true, 20 -> 20, 0\n// f(bool,uint256): false, 20 -> 0, 20\n" + }, + "conditional_expression_false_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return false ? 5 : 10;\n }\n}\n// ----\n// f() -> 10\n" + }, + "exp_operator_const_signed.sol": { + "content": "contract test {\n function f() public returns(int d) { return (-2) ** 3; }\n}\n// ----\n// f() -> -8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal.sol b/examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal.sol new file mode 100644 index 00000000..f7e5c6ab --- /dev/null +++ b/examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal.sol @@ -0,0 +1,5 @@ +contract test { + function f() public returns(uint d) { return 0 ** 0; } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal_standard_input.json b/examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal_standard_input.json new file mode 100644 index 00000000..5e3c2a61 --- /dev/null +++ b/examples/test/semanticTests/expressions_exp_zero_literal/exp_zero_literal_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators.sol b/examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators.sol new file mode 100644 index 00000000..c6957ee9 --- /dev/null +++ b/examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators.sol @@ -0,0 +1,15 @@ +contract test { + uint8 x; + uint v; + function f() public returns (uint r) { + uint a = 6; + r = a; + r += (a++) * 0x10; + r += (++a) * 0x100; + v = 3; + r += (v++) * 0x1000; + r += (++v) * 0x10000; + } +} +// ---- +// f() -> 0x053866 diff --git a/examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators_standard_input.json b/examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators_standard_input.json new file mode 100644 index 00000000..a0206de6 --- /dev/null +++ b/examples/test/semanticTests/expressions_inc_dec_operators/inc_dec_operators_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression.sol b/examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression.sol new file mode 100644 index 00000000..937d06c1 --- /dev/null +++ b/examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression.sol @@ -0,0 +1,15 @@ +==== Source: A ==== +contract D { +} +==== Source: B ==== +import "A" as M; + +contract C { + function f() public pure returns (bool) { + bool flag; + ((flag = true) ? M : M).D; + return flag; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression_standard_input.json b/examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression_standard_input.json new file mode 100644 index 00000000..2148a715 --- /dev/null +++ b/examples/test/semanticTests/expressions_module_from_ternary_expression/module_from_ternary_expression_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression.sol b/examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression.sol new file mode 100644 index 00000000..c8a2ced2 --- /dev/null +++ b/examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (bool){ + bool flag; + ((flag = true) ? (1, 2, 3) : (3, 2, 1)); + return flag; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression_standard_input.json b/examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression_standard_input.json new file mode 100644 index 00000000..ce1f24f0 --- /dev/null +++ b/examples/test/semanticTests/expressions_tuple_from_ternary_expression/tuple_from_ternary_expression_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + }, + "conditional_expression_storage_memory_1.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n bytes2[2] memory x;\n x[0] = \"aa\";\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n data1 = cond ? x : y;\n\n uint ret = 0;\n if (data1[0] == \"aa\")\n {\n ret = 1;\n }\n\n if (data1[0] == \"bb\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "conditional_expression_different_types.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint) {\n uint8 x = 0xcd;\n uint16 y = 0xabab;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0xcd\n// f(bool): false -> 0xabab\n" + }, + "tuple_from_ternary_expression.sol": { + "content": "contract C {\n function f() public pure returns (bool){\n bool flag;\n ((flag = true) ? (1, 2, 3) : (3, 2, 1));\n return flag;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal.sol b/examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal.sol new file mode 100644 index 00000000..29bf6616 --- /dev/null +++ b/examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (bool) { + return + 0 < + ~~84926290883049832306107864558384249403874903260938453235235091622489261765859; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal_standard_input.json b/examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal_standard_input.json new file mode 100644 index 00000000..99dcaa37 --- /dev/null +++ b/examples/test/semanticTests/expressions_unary_too_long_literal/unary_too_long_literal_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + }, + "conditional_expression_multiple.sol": { + "content": "contract test {\n function f(uint x) public returns(uint d) {\n return x > 100 ?\n x > 1000 ? 1000 : 100\n :\n x > 50 ? 50 : 10;\n }\n}\n// ----\n// f(uint256): 1001 -> 1000\n// f(uint256): 500 -> 100\n// f(uint256): 80 -> 50\n// f(uint256): 40 -> 10\n" + }, + "conditional_expression_storage_memory_2.sol": { + "content": "contract test {\n bytes2[2] data1;\n function f(bool cond) public returns (uint) {\n data1[0] = \"cc\";\n\n bytes2[2] memory x;\n bytes2[2] memory y;\n y[0] = \"bb\";\n\n x = cond ? y : data1;\n\n uint ret = 0;\n if (x[0] == \"bb\")\n {\n ret = 1;\n }\n\n if (x[0] == \"cc\")\n {\n ret = 2;\n }\n\n return ret;\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "exp_zero_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 0 ** 0; }\n}\n// ----\n// f() -> 1\n" + }, + "unary_too_long_literal.sol": { + "content": "contract C {\n\tfunction f() public returns (bool) {\n\t\treturn\n\t\t\t0 <\n\t\t\t~~84926290883049832306107864558384249403874903260938453235235091622489261765859;\n\t}\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send.sol b/examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send.sol new file mode 100644 index 00000000..af408b3f --- /dev/null +++ b/examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send.sol @@ -0,0 +1,10 @@ +contract TransferTest { + fallback() external payable { + // This used to cause an ICE + payable(this).transfer; + } + + function f() pure public {} +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send_standard_input.json b/examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send_standard_input.json new file mode 100644 index 00000000..2776ad9e --- /dev/null +++ b/examples/test/semanticTests/expressions_uncalled_address_transfer_send/uncalled_address_transfer_send_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "conditional_expression_true_literal.sol": { + "content": "contract test {\n function f() public returns(uint d) {\n return true ? 5 : 10;\n }\n}\n// ----\n// f() -> 5\n" + }, + "conditional_expression_functions.sol": { + "content": "contract test {\n function x() public returns (uint) { return 1; }\n function y() public returns (uint) { return 2; }\n\n function f(bool cond) public returns (uint) {\n function () returns (uint) z = cond ? x : y;\n return z();\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "inc_dec_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint r) {\n uint a = 6;\n r = a;\n r += (a++) * 0x10;\n r += (++a) * 0x100;\n v = 3;\n r += (v++) * 0x1000;\n r += (++v) * 0x10000;\n }\n}\n// ----\n// f() -> 0x053866\n" + }, + "module_from_ternary_expression.sol": { + "content": "==== Source: A ====\ncontract D {\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract C {\n function f() public pure returns (bool) {\n bool flag;\n ((flag = true) ? M : M).D;\n return flag;\n }\n}\n// ----\n// f() -> true\n" + }, + "bit_operators.sol": { + "content": "contract test {\n uint8 x;\n uint v;\n function f() public returns (uint x, uint y, uint z) {\n uint16 a;\n uint32 b;\n assembly {\n a := 0x0f0f0f0f0f\n b := 0xff0fff0fff\n }\n x = a & b;\n y = a | b;\n z = a ^ b;\n }\n}\n// ----\n// f() -> 3855, 268374015, 268370160\n" + }, + "bytes_comparison.sol": { + "content": "contract test {\n function f() public returns (bool) {\n bytes2 a = \"a\";\n bytes2 x = \"aa\";\n bytes2 b = \"b\";\n return a < x && x < b;\n }\n}\n// ----\n// f() -> true\n" + }, + "exp_operator_const.sol": { + "content": "contract test {\n function f() public returns(uint d) { return 2 ** 3; }\n}\n// ----\n// f() -> 8\n" + }, + "conditional_expression_tuples.sol": { + "content": "contract test {\n function f(bool cond) public returns (uint, uint) {\n return cond ? (1, 2) : (3, 4);\n }\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "uncalled_address_transfer_send.sol": { + "content": "contract TransferTest {\n\tfallback() external payable {\n\t\t// This used to cause an ICE\n\t\tpayable(this).transfer;\n\t}\n\n\tfunction f() pure public {}\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar.sol b/examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar.sol new file mode 100644 index 00000000..47feaf52 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar.sol @@ -0,0 +1,121 @@ +//sol FixedFeeRegistrar +// Simple global registrar with fixed-fee reservations. +// @authors: +// Gav Wood + +pragma solidity >=0.4.0 <0.9.0; + +abstract contract Registrar { + event Changed(string indexed name); + + function owner(string memory _name) public virtual view returns (address o_owner); + function addr(string memory _name) public virtual view returns (address o_address); + function subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar); + function content(string memory _name) public virtual view returns (bytes32 o_content); +} + +contract FixedFeeRegistrar is Registrar { + struct Record { + address addr; + address subRegistrar; + bytes32 content; + address owner; + } + + modifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; } + + function reserve(string memory _name) public payable { + Record storage rec = m_record(_name); + if (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) { + rec.owner = msg.sender; + emit Changed(_name); + } + } + function disown(string memory _name, address payable _refund) onlyrecordowner(_name) public { + delete m_recordData[uint(keccak256(bytes(_name))) / 8]; + if (!_refund.send(c_fee)) + revert(); + emit Changed(_name); + } + function transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public { + m_record(_name).owner = _newOwner; + emit Changed(_name); + } + function setAddr(string memory _name, address _a) onlyrecordowner(_name) public { + m_record(_name).addr = _a; + emit Changed(_name); + } + function setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public { + m_record(_name).subRegistrar = _registrar; + emit Changed(_name); + } + function setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public { + m_record(_name).content = _content; + emit Changed(_name); + } + + function record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) { + Record storage rec = m_record(_name); + o_addr = rec.addr; + o_subRegistrar = rec.subRegistrar; + o_content = rec.content; + o_owner = rec.owner; + } + function addr(string memory _name) public override view returns (address) { return m_record(_name).addr; } + function subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; } + function content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; } + function owner(string memory _name) public override view returns (address) { return m_record(_name).owner; } + + Record[2**253] m_recordData; + function m_record(string memory _name) view internal returns (Record storage o_record) { + return m_recordData[uint(keccak256(bytes(_name))) / 8]; + } + uint constant c_fee = 69 ether; +} +// ---- +// constructor() +// gas irOptimized: 78076 +// gas irOptimized code: 307400 +// gas legacy: 115395 +// gas legacy code: 792400 +// gas legacyOptimized: 84598 +// gas legacyOptimized code: 388000 +// reserve(string), 69 ether: 0x20, 3, "abc" -> +// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 +// gas irOptimized: 45967 +// gas legacy: 46842 +// gas legacyOptimized: 46091 +// owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012 +// reserve(string), 70 ether: 0x20, 3, "def" -> +// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c +// owner(string): 0x20, 3, "def" -> 0x1212121212121212121212121212120000000012 +// reserve(string), 68 ether: 0x20, 3, "ghi" -> +// owner(string): 0x20, 3, "ghi" -> 0 +// account: 1 -> 0x1212121212121212121212121212120000001012 +// reserve(string), 69 ether: 0x20, 3, "abc" -> +// owner(string): 0x20, 3, "abc" -> 0x1212121212121212121212121212120000000012 +// account: 0 -> 0x1212121212121212121212121212120000000012 +// setContent(string,bytes32): 0x40, 0, 3, "abc" -> +// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 +// transfer(string,address): 0x40, 555, 3, "abc" -> +// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 +// owner(string): 0x20, 3, "abc" -> 555 +// content(string): 0x20, 3, "abc" -> 0x00 +// setContent(string,bytes32): 0x40, 333, 3, "def" -> +// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c +// setAddr(string,address): 0x40, 124, 3, "def" -> +// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c +// setSubRegistrar(string,address): 0x40, 125, 3, "def" -> +// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c +// content(string): 0x20, 3, "def" -> 333 +// addr(string): 0x20, 3, "def" -> 124 +// subRegistrar(string): 0x20, 3, "def" -> 125 +// balance: 0x124 -> 0 +// disown(string,address): 0x40, 0x124, 3, "def" -> +// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c +// balance: 0x124 -> 0 +// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c +// owner(string): 0x20, 3, "def" -> 0 +// content(string): 0x20, 3, "def" -> 0 +// addr(string): 0x20, 3, "def" -> 0 +// subRegistrar(string): 0x20, 3, "def" -> 0 diff --git a/examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar_standard_input.json b/examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar_standard_input.json new file mode 100644 index 00000000..07210745 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_FixedFeeRegistrar/FixedFeeRegistrar_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm.sol b/examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm.sol new file mode 100644 index 00000000..7df0c902 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm.sol @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Provides a set of functions to operate with Base64 strings. + */ +library InlineAsmBase64 { + /** + * @dev Base64 Encoding/Decoding Table + */ + string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + /** + * @dev Converts a `bytes` to its Bytes64 `string` representation. + */ + function encode(bytes memory data) internal pure returns (string memory) { + /** + * Inspired by OpenZepplin Base64 implementation + * https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2884/commits/157c32b65a15cb0b58257543643cafa1cebf883a + */ + if (data.length == 0) return ""; + + // Loads the table into memory + string memory table = _TABLE; + + // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter + // and split into 4 numbers of 6 bits. + // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up + // - `data.length + 2` -> Round up + // - `/ 3` -> Number of 3-bytes chunks + // - `4 *` -> 4 characters for each chunk + uint256 encodedLen = 4 * ((data.length + 2) / 3); + + // Add some extra buffer at the end required for the writing + string memory result = new string(encodedLen); + + assembly { + // Store the actual result length in memory + mstore(result, encodedLen) + + // Prepare the lookup table + let tablePtr := add(table, 1) + + // Prepare input pointer + let dataPtr := data + let endPtr := add(dataPtr, mload(data)) + + // Prepare result pointer, jump over length + let resultPtr := add(result, 32) + + // Run over the input, 3 bytes at a time + for { + + } lt(dataPtr, endPtr) { + + } { + // Advance 3 bytes + dataPtr := add(dataPtr, 3) + let input := mload(dataPtr) + + // To write each character, shift the 3 bytes (24 bits) chunk 4 + // times in blocks of 6 bits for each character (18, 12, 6, 0) + // and apply logical AND with 0x3F to extract the 6-bit group. + // Add the 6-bit group with the table ptr to index into the + // table and acquire the character to write. Finally, write + // the character to the result pointer. + + mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) + resultPtr := add(resultPtr, 1) // Advance + + mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) + resultPtr := add(resultPtr, 1) // Advance + + mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) + resultPtr := add(resultPtr, 1) // Advance + + mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) + resultPtr := add(resultPtr, 1) // Advance + } + + // When data `bytes` is not exactly 3 bytes long + // it is padded with `=` characters at the end + switch mod(mload(data), 3) + case 1 { + mstore8(sub(resultPtr, 1), 0x3d) + mstore8(sub(resultPtr, 2), 0x3d) + } + case 2 { + mstore8(sub(resultPtr, 1), 0x3d) + } + } + + return result; + } +} diff --git a/examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm_standard_input.json b/examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm_standard_input.json new file mode 100644 index 00000000..7cd4f1dc --- /dev/null +++ b/examples/test/semanticTests/externalContracts__base64_base64_inline_asm/base64_inline_asm_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "base64_no_inline_asm.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary NoAsmBase64 {\n bytes private constant TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n function encode(bytes memory data) internal pure returns (string memory) {\n if (data.length == 0) return \"\";\n\n bytes memory table = TABLE;\n bytes memory result = new bytes(4 * ((data.length + 2) / 3));\n uint256 resultPtr = 0;\n\n for (uint256 dataPtr = 0; dataPtr < data.length; dataPtr += 3) {\n uint24 chunk = ( (uint24(uint8(data[dataPtr + 0])) << 16))\n + (dataPtr + 1 < data.length ? (uint24(uint8(data[dataPtr + 1])) << 8) : 0)\n + (dataPtr + 2 < data.length ? (uint24(uint8(data[dataPtr + 2])) ) : 0);\n\n result[resultPtr++] = table[uint8(chunk >> 18) & 0x3f];\n result[resultPtr++] = table[uint8(chunk >> 12) & 0x3f];\n result[resultPtr++] = table[uint8(chunk >> 6) & 0x3f];\n result[resultPtr++] = table[uint8(chunk ) & 0x3f];\n }\n\n if (data.length % 3 == 1) {\n result[--resultPtr] = 0x3d;\n result[--resultPtr] = 0x3d;\n }\n else if (data.length % 3 == 2) {\n result[--resultPtr] = 0x3d;\n }\n\n return (string(result));\n }\n}\n" + }, + "base64_inline_asm.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary InlineAsmBase64 {\n /**\n * @dev Base64 Encoding/Decoding Table\n */\n string internal constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n /**\n * @dev Converts a `bytes` to its Bytes64 `string` representation.\n */\n function encode(bytes memory data) internal pure returns (string memory) {\n /**\n * Inspired by OpenZepplin Base64 implementation\n * https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2884/commits/157c32b65a15cb0b58257543643cafa1cebf883a\n */\n if (data.length == 0) return \"\";\n\n // Loads the table into memory\n string memory table = _TABLE;\n\n // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter\n // and split into 4 numbers of 6 bits.\n // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up\n // - `data.length + 2` -> Round up\n // - `/ 3` -> Number of 3-bytes chunks\n // - `4 *` -> 4 characters for each chunk\n uint256 encodedLen = 4 * ((data.length + 2) / 3);\n\n // Add some extra buffer at the end required for the writing\n string memory result = new string(encodedLen);\n\n assembly {\n // Store the actual result length in memory\n mstore(result, encodedLen)\n\n // Prepare the lookup table\n let tablePtr := add(table, 1)\n\n // Prepare input pointer\n let dataPtr := data\n let endPtr := add(dataPtr, mload(data))\n\n // Prepare result pointer, jump over length\n let resultPtr := add(result, 32)\n\n // Run over the input, 3 bytes at a time\n for {\n\n } lt(dataPtr, endPtr) {\n\n } {\n // Advance 3 bytes\n dataPtr := add(dataPtr, 3)\n let input := mload(dataPtr)\n\n // To write each character, shift the 3 bytes (24 bits) chunk 4\n // times in blocks of 6 bits for each character (18, 12, 6, 0)\n // and apply logical AND with 0x3F to extract the 6-bit group.\n // Add the 6-bit group with the table ptr to index into the\n // table and acquire the character to write. Finally, write\n // the character to the result pointer.\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n\n mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n resultPtr := add(resultPtr, 1) // Advance\n }\n\n // When data `bytes` is not exactly 3 bytes long\n // it is padded with `=` characters at the end\n switch mod(mload(data), 3)\n case 1 {\n mstore8(sub(resultPtr, 1), 0x3d)\n mstore8(sub(resultPtr, 2), 0x3d)\n }\n case 2 {\n mstore8(sub(resultPtr, 1), 0x3d)\n }\n }\n\n return result;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm.sol b/examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm.sol new file mode 100644 index 00000000..f54d2f92 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Provides a set of functions to operate with Base64 strings. + */ +library NoAsmBase64 { + bytes private constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + function encode(bytes memory data) internal pure returns (string memory) { + if (data.length == 0) return ""; + + bytes memory table = TABLE; + bytes memory result = new bytes(4 * ((data.length + 2) / 3)); + uint256 resultPtr = 0; + + for (uint256 dataPtr = 0; dataPtr < data.length; dataPtr += 3) { + uint24 chunk = ( (uint24(uint8(data[dataPtr + 0])) << 16)) + + (dataPtr + 1 < data.length ? (uint24(uint8(data[dataPtr + 1])) << 8) : 0) + + (dataPtr + 2 < data.length ? (uint24(uint8(data[dataPtr + 2])) ) : 0); + + result[resultPtr++] = table[uint8(chunk >> 18) & 0x3f]; + result[resultPtr++] = table[uint8(chunk >> 12) & 0x3f]; + result[resultPtr++] = table[uint8(chunk >> 6) & 0x3f]; + result[resultPtr++] = table[uint8(chunk ) & 0x3f]; + } + + if (data.length % 3 == 1) { + result[--resultPtr] = 0x3d; + result[--resultPtr] = 0x3d; + } + else if (data.length % 3 == 2) { + result[--resultPtr] = 0x3d; + } + + return (string(result)); + } +} diff --git a/examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm_standard_input.json b/examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm_standard_input.json new file mode 100644 index 00000000..580b631a --- /dev/null +++ b/examples/test/semanticTests/externalContracts__base64_base64_no_inline_asm/base64_no_inline_asm_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "base64_no_inline_asm.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides a set of functions to operate with Base64 strings.\n */\nlibrary NoAsmBase64 {\n bytes private constant TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n function encode(bytes memory data) internal pure returns (string memory) {\n if (data.length == 0) return \"\";\n\n bytes memory table = TABLE;\n bytes memory result = new bytes(4 * ((data.length + 2) / 3));\n uint256 resultPtr = 0;\n\n for (uint256 dataPtr = 0; dataPtr < data.length; dataPtr += 3) {\n uint24 chunk = ( (uint24(uint8(data[dataPtr + 0])) << 16))\n + (dataPtr + 1 < data.length ? (uint24(uint8(data[dataPtr + 1])) << 8) : 0)\n + (dataPtr + 2 < data.length ? (uint24(uint8(data[dataPtr + 2])) ) : 0);\n\n result[resultPtr++] = table[uint8(chunk >> 18) & 0x3f];\n result[resultPtr++] = table[uint8(chunk >> 12) & 0x3f];\n result[resultPtr++] = table[uint8(chunk >> 6) & 0x3f];\n result[resultPtr++] = table[uint8(chunk ) & 0x3f];\n }\n\n if (data.length % 3 == 1) {\n result[--resultPtr] = 0x3d;\n result[--resultPtr] = 0x3d;\n }\n else if (data.length % 3 == 2) {\n result[--resultPtr] = 0x3d;\n }\n\n return (string(result));\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon.sol b/examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon.sol new file mode 100644 index 00000000..a3b49f8d --- /dev/null +++ b/examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon.sol @@ -0,0 +1,361 @@ +// SPDX-License-Identifier: WTFPL +pragma solidity >=0.8.0; + +/// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library +/// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point +// representation. When it does not, it is annotated in the function's NatSpec documentation. +library PRBMathCommon { + /// @dev How many trailing decimals can be represented. + uint256 internal constant SCALE = 1e18; + + /// @dev Largest power of two divisor of SCALE. + uint256 internal constant SCALE_LPOTD = 262144; + + /// @dev SCALE inverted mod 2^256. + uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661508869554232690281; + + /// @notice Calculates the binary exponent of x using the binary fraction method. + /// @dev Uses 128.128-bit fixed-point numbers, which is the most efficient way. + /// See https://ethereum.stackexchange.com/a/96594/24693. + /// @param x The exponent as an unsigned 128.128-bit fixed-point number. + /// @return result The result as an unsigned 60x18 decimal fixed-point number. + function exp2(uint256 x) internal pure returns (uint256 result) { + unchecked { + // Start from 0.5 in the 128.128-bit fixed-point format. + result = 0x80000000000000000000000000000000; + + // Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows + // because the initial result is 2^127 and all magic factors are less than 2^129. + if (x & 0x80000000000000000000000000000000 > 0) result = (result * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128; + if (x & 0x40000000000000000000000000000000 > 0) result = (result * 0x1306FE0A31B7152DE8D5A46305C85EDED) >> 128; + if (x & 0x20000000000000000000000000000000 > 0) result = (result * 0x1172B83C7D517ADCDF7C8C50EB14A7920) >> 128; + if (x & 0x10000000000000000000000000000000 > 0) result = (result * 0x10B5586CF9890F6298B92B71842A98364) >> 128; + if (x & 0x8000000000000000000000000000000 > 0) result = (result * 0x1059B0D31585743AE7C548EB68CA417FE) >> 128; + if (x & 0x4000000000000000000000000000000 > 0) result = (result * 0x102C9A3E778060EE6F7CACA4F7A29BDE9) >> 128; + if (x & 0x2000000000000000000000000000000 > 0) result = (result * 0x10163DA9FB33356D84A66AE336DCDFA40) >> 128; + if (x & 0x1000000000000000000000000000000 > 0) result = (result * 0x100B1AFA5ABCBED6129AB13EC11DC9544) >> 128; + if (x & 0x800000000000000000000000000000 > 0) result = (result * 0x10058C86DA1C09EA1FF19D294CF2F679C) >> 128; + if (x & 0x400000000000000000000000000000 > 0) result = (result * 0x1002C605E2E8CEC506D21BFC89A23A011) >> 128; + if (x & 0x200000000000000000000000000000 > 0) result = (result * 0x100162F3904051FA128BCA9C55C31E5E0) >> 128; + if (x & 0x100000000000000000000000000000 > 0) result = (result * 0x1000B175EFFDC76BA38E31671CA939726) >> 128; + if (x & 0x80000000000000000000000000000 > 0) result = (result * 0x100058BA01FB9F96D6CACD4B180917C3E) >> 128; + if (x & 0x40000000000000000000000000000 > 0) result = (result * 0x10002C5CC37DA9491D0985C348C68E7B4) >> 128; + if (x & 0x20000000000000000000000000000 > 0) result = (result * 0x1000162E525EE054754457D5995292027) >> 128; + if (x & 0x10000000000000000000000000000 > 0) result = (result * 0x10000B17255775C040618BF4A4ADE83FD) >> 128; + if (x & 0x8000000000000000000000000000 > 0) result = (result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAC) >> 128; + if (x & 0x4000000000000000000000000000 > 0) result = (result * 0x100002C5C89D5EC6CA4D7C8ACC017B7CA) >> 128; + if (x & 0x2000000000000000000000000000 > 0) result = (result * 0x10000162E43F4F831060E02D839A9D16D) >> 128; + if (x & 0x1000000000000000000000000000 > 0) result = (result * 0x100000B1721BCFC99D9F890EA06911763) >> 128; + if (x & 0x800000000000000000000000000 > 0) result = (result * 0x10000058B90CF1E6D97F9CA14DBCC1629) >> 128; + if (x & 0x400000000000000000000000000 > 0) result = (result * 0x1000002C5C863B73F016468F6BAC5CA2C) >> 128; + if (x & 0x200000000000000000000000000 > 0) result = (result * 0x100000162E430E5A18F6119E3C02282A6) >> 128; + if (x & 0x100000000000000000000000000 > 0) result = (result * 0x1000000B1721835514B86E6D96EFD1BFF) >> 128; + if (x & 0x80000000000000000000000000 > 0) result = (result * 0x100000058B90C0B48C6BE5DF846C5B2F0) >> 128; + if (x & 0x40000000000000000000000000 > 0) result = (result * 0x10000002C5C8601CC6B9E94213C72737B) >> 128; + if (x & 0x20000000000000000000000000 > 0) result = (result * 0x1000000162E42FFF037DF38AA2B219F07) >> 128; + if (x & 0x10000000000000000000000000 > 0) result = (result * 0x10000000B17217FBA9C739AA5819F44FA) >> 128; + if (x & 0x8000000000000000000000000 > 0) result = (result * 0x1000000058B90BFCDEE5ACD3C1CEDC824) >> 128; + if (x & 0x4000000000000000000000000 > 0) result = (result * 0x100000002C5C85FE31F35A6A30DA1BE51) >> 128; + if (x & 0x2000000000000000000000000 > 0) result = (result * 0x10000000162E42FF0999CE3541B9FFFD0) >> 128; + if (x & 0x1000000000000000000000000 > 0) result = (result * 0x100000000B17217F80F4EF5AADDA45554) >> 128; + if (x & 0x800000000000000000000000 > 0) result = (result * 0x10000000058B90BFBF8479BD5A81B51AE) >> 128; + if (x & 0x400000000000000000000000 > 0) result = (result * 0x1000000002C5C85FDF84BD62AE30A74CD) >> 128; + if (x & 0x200000000000000000000000 > 0) result = (result * 0x100000000162E42FEFB2FED257559BDAA) >> 128; + if (x & 0x100000000000000000000000 > 0) result = (result * 0x1000000000B17217F7D5A7716BBA4A9AF) >> 128; + if (x & 0x80000000000000000000000 > 0) result = (result * 0x100000000058B90BFBE9DDBAC5E109CCF) >> 128; + if (x & 0x40000000000000000000000 > 0) result = (result * 0x10000000002C5C85FDF4B15DE6F17EB0E) >> 128; + if (x & 0x20000000000000000000000 > 0) result = (result * 0x1000000000162E42FEFA494F1478FDE05) >> 128; + if (x & 0x10000000000000000000000 > 0) result = (result * 0x10000000000B17217F7D20CF927C8E94D) >> 128; + if (x & 0x8000000000000000000000 > 0) result = (result * 0x1000000000058B90BFBE8F71CB4E4B33E) >> 128; + if (x & 0x4000000000000000000000 > 0) result = (result * 0x100000000002C5C85FDF477B662B26946) >> 128; + if (x & 0x2000000000000000000000 > 0) result = (result * 0x10000000000162E42FEFA3AE53369388D) >> 128; + if (x & 0x1000000000000000000000 > 0) result = (result * 0x100000000000B17217F7D1D351A389D41) >> 128; + if (x & 0x800000000000000000000 > 0) result = (result * 0x10000000000058B90BFBE8E8B2D3D4EDF) >> 128; + if (x & 0x400000000000000000000 > 0) result = (result * 0x1000000000002C5C85FDF4741BEA6E77F) >> 128; + if (x & 0x200000000000000000000 > 0) result = (result * 0x100000000000162E42FEFA39FE95583C3) >> 128; + if (x & 0x100000000000000000000 > 0) result = (result * 0x1000000000000B17217F7D1CFB72B45E3) >> 128; + if (x & 0x80000000000000000000 > 0) result = (result * 0x100000000000058B90BFBE8E7CC35C3F2) >> 128; + if (x & 0x40000000000000000000 > 0) result = (result * 0x10000000000002C5C85FDF473E242EA39) >> 128; + if (x & 0x20000000000000000000 > 0) result = (result * 0x1000000000000162E42FEFA39F02B772C) >> 128; + if (x & 0x10000000000000000000 > 0) result = (result * 0x10000000000000B17217F7D1CF7D83C1A) >> 128; + if (x & 0x8000000000000000000 > 0) result = (result * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128; + if (x & 0x4000000000000000000 > 0) result = (result * 0x100000000000002C5C85FDF473DEA871F) >> 128; + if (x & 0x2000000000000000000 > 0) result = (result * 0x10000000000000162E42FEFA39EF44D92) >> 128; + if (x & 0x1000000000000000000 > 0) result = (result * 0x100000000000000B17217F7D1CF79E949) >> 128; + if (x & 0x800000000000000000 > 0) result = (result * 0x10000000000000058B90BFBE8E7BCE545) >> 128; + if (x & 0x400000000000000000 > 0) result = (result * 0x1000000000000002C5C85FDF473DE6ECA) >> 128; + if (x & 0x200000000000000000 > 0) result = (result * 0x100000000000000162E42FEFA39EF366F) >> 128; + if (x & 0x100000000000000000 > 0) result = (result * 0x1000000000000000B17217F7D1CF79AFA) >> 128; + if (x & 0x80000000000000000 > 0) result = (result * 0x100000000000000058B90BFBE8E7BCD6E) >> 128; + if (x & 0x40000000000000000 > 0) result = (result * 0x10000000000000002C5C85FDF473DE6B3) >> 128; + if (x & 0x20000000000000000 > 0) result = (result * 0x1000000000000000162E42FEFA39EF359) >> 128; + if (x & 0x10000000000000000 > 0) result = (result * 0x10000000000000000B17217F7D1CF79AC) >> 128; + + // We do two things at the same time below: + // + // 1. Multiply the result by 2^n + 1, where 2^n is the integer part and 1 is an extra bit to account + // for the fact that we initially set the result to 0.5 We implement this by subtracting from 127 + // instead of 128. + // 2. Convert the result to the unsigned 60.18-decimal fixed-point format. + // + // This works because result * SCALE * 2^ip / 2^127 = result * SCALE / 2^(127 - ip), where ip is the integer + // part and SCALE / 2^128 is what converts the result to our unsigned fixed-point format. + result *= SCALE; + result >>= (127 - (x >> 128)); + } + } + + /// @notice Finds the zero-based index of the first one in the binary representation of x. + /// @dev See the note on msb in the "Find First Set" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set + /// @param x The uint256 number for which to find the index of the most significant bit. + /// @return msb The index of the most significant bit as an uint256. + function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) { + if (x >= 2**128) { + x >>= 128; + msb += 128; + } + if (x >= 2**64) { + x >>= 64; + msb += 64; + } + if (x >= 2**32) { + x >>= 32; + msb += 32; + } + if (x >= 2**16) { + x >>= 16; + msb += 16; + } + if (x >= 2**8) { + x >>= 8; + msb += 8; + } + if (x >= 2**4) { + x >>= 4; + msb += 4; + } + if (x >= 2**2) { + x >>= 2; + msb += 2; + } + if (x >= 2**1) { + // No need to shift x any more. + msb += 1; + } + } + + /// @notice Calculates floor(x*y÷denominator) with full precision. + /// + /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv. + /// + /// Requirements: + /// - The denominator cannot be zero. + /// - The result must fit within uint256. + /// + /// Caveats: + /// - This function does not work with fixed-point numbers. + /// + /// @param x The multiplicand as an uint256. + /// @param y The multiplier as an uint256. + /// @param denominator The divisor as an uint256. + /// @return result The result as an uint256. + function mulDiv( + uint256 x, + uint256 y, + uint256 denominator + ) internal pure returns (uint256 result) { + // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2**256 and mod 2**256 - 1, then use + // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 + // variables such that product = prod1 * 2**256 + prod0. + uint256 prod0; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly { + let mm := mulmod(x, y, not(0)) + prod0 := mul(x, y) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division + if (prod1 == 0) { + require(denominator > 0); + assembly { + result := div(prod0, denominator) + } + return result; + } + + // Make sure the result is less than 2**256. Also prevents denominator == 0. + require(denominator > prod1); + + /////////////////////////////////////////////// + // 512 by 256 division. + /////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0]. + uint256 remainder; + assembly { + // Compute remainder using mulmod. + remainder := mulmod(x, y, denominator) + + // Subtract 256 bit number from 512 bit number + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. + // See https://cs.stackexchange.com/q/138556/92363. + unchecked { + // Does not overflow because the denominator cannot be zero at this stage in the function. + uint256 lpotdod = denominator & (~denominator + 1); + assembly { + // Divide denominator by lpotdod. + denominator := div(denominator, lpotdod) + + // Divide [prod1 prod0] by lpotdod. + prod0 := div(prod0, lpotdod) + + // Flip lpotdod such that it is 2**256 / lpotdod. If lpotdod is zero, then it becomes one. + lpotdod := add(div(sub(0, lpotdod), lpotdod), 1) + } + + // Shift in bits from prod1 into prod0. + prod0 |= prod1 * lpotdod; + + // Invert denominator mod 2**256. Now that denominator is an odd number, it has an inverse modulo 2**256 such + // that denominator * inv = 1 mod 2**256. Compute the inverse by starting with a seed that is correct for + // four bits. That is, denominator * inv = 1 mod 2**4 + uint256 inverse = (3 * denominator) ^ 2; + + // Now use Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works + // in modular arithmetic, doubling the correct bits in each step. + inverse *= 2 - denominator * inverse; // inverse mod 2**8 + inverse *= 2 - denominator * inverse; // inverse mod 2**16 + inverse *= 2 - denominator * inverse; // inverse mod 2**32 + inverse *= 2 - denominator * inverse; // inverse mod 2**64 + inverse *= 2 - denominator * inverse; // inverse mod 2**128 + inverse *= 2 - denominator * inverse; // inverse mod 2**256 + + // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. + // This will give us the correct result modulo 2**256. Since the precoditions guarantee that the outcome is + // less than 2**256, this is the final result. We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inverse; + return result; + } + } + + /// @notice Calculates floor(x*y÷1e18) with full precision. + /// + /// @dev Variant of "mulDiv" with constant folding, i.e. in which the denominator is always 1e18. Before returning the + /// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of + /// being rounded to 1e-18. See "Listing 6" and text above it at https://accu.org/index.php/journals/1717. + /// + /// Requirements: + /// - The result must fit within uint256. + /// + /// Caveats: + /// - The body is purposely left uncommented; see the NatSpec comments in "PRBMathCommon.mulDiv" to understand how this works. + /// - It is assumed that the result can never be type(uint256).max when x and y solve the following two equations: + /// 1. x * y = type(uint256).max * SCALE + /// 2. (x * y) % SCALE >= SCALE / 2 + /// + /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number. + /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number. + /// @return result The result as an unsigned 60.18-decimal fixed-point number. + function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) { + uint256 prod0; + uint256 prod1; + assembly { + let mm := mulmod(x, y, not(0)) + prod0 := mul(x, y) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + uint256 remainder; + uint256 roundUpUnit; + assembly { + remainder := mulmod(x, y, SCALE) + roundUpUnit := gt(remainder, 499999999999999999) + } + + if (prod1 == 0) { + unchecked { + result = (prod0 / SCALE) + roundUpUnit; + return result; + } + } + + require(SCALE > prod1); + + assembly { + result := add( + mul( + or( + div(sub(prod0, remainder), SCALE_LPOTD), + mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1)) + ), + SCALE_INVERSE + ), + roundUpUnit + ) + } + } + + /// @notice Calculates the square root of x, rounding down. + /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method. + /// + /// Caveats: + /// - This function does not work with fixed-point numbers. + /// + /// @param x The uint256 number for which to calculate the square root. + /// @return result The result as an uint256. + function sqrt(uint256 x) internal pure returns (uint256 result) { + if (x == 0) { + return 0; + } + + // Calculate the square root of the perfect square of a power of two that is the closest to x. + uint256 xAux = uint256(x); + result = 1; + if (xAux >= 0x100000000000000000000000000000000) { + xAux >>= 128; + result <<= 64; + } + if (xAux >= 0x10000000000000000) { + xAux >>= 64; + result <<= 32; + } + if (xAux >= 0x100000000) { + xAux >>= 32; + result <<= 16; + } + if (xAux >= 0x10000) { + xAux >>= 16; + result <<= 8; + } + if (xAux >= 0x100) { + xAux >>= 8; + result <<= 4; + } + if (xAux >= 0x10) { + xAux >>= 4; + result <<= 2; + } + if (xAux >= 0x8) { + result <<= 1; + } + + // The operations can never overflow because the result is max 2^127 when it enters this block. + unchecked { + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; + result = (result + x / result) >> 1; // Seven iterations should be enough + uint256 roundedDownResult = x / result; + return result >= roundedDownResult ? roundedDownResult : result; + } + } +} diff --git a/examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon_standard_input.json b/examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon_standard_input.json new file mode 100644 index 00000000..52381189 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__prbmath_PRBMathCommon/PRBMathCommon_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "PRBMathSD59x18.sol": { + "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathSD59x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with int256 numbers considered to have 18\n/// trailing decimals. We call this number representation signed 59.18-decimal fixed-point, since the numbers can have\n/// a sign and there can be up to 59 digits in the integer part and up to 18 decimals in the fractional part. The numbers\n/// are bound by the minimum and the maximum values permitted by the Solidity type int256.\nlibrary PRBMathSD59x18 {\n /// @dev log2(e) as a signed 59.18-decimal fixed-point number.\n int256 internal constant LOG2_E = 1442695040888963407;\n\n /// @dev Half the SCALE number.\n int256 internal constant HALF_SCALE = 5e17;\n\n /// @dev The maximum value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728792003956564819967;\n\n /// @dev The maximum whole value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n /// @dev The minimum value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n /// @dev The minimum whole value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n /// @dev How many trailing decimals can be represented.\n int256 internal constant SCALE = 1e18;\n\n /// INTERNAL FUNCTIONS ///\n\n /// @notice Calculate the absolute value of x.\n ///\n /// @dev Requirements:\n /// - x must be greater than MIN_SD59x18.\n ///\n /// @param x The number to calculate the absolute value for.\n /// @param result The absolute value of x.\n function abs(int256 x) internal pure returns (int256 result) {\n unchecked {\n require(x > MIN_SD59x18);\n result = x < 0 ? -x : x;\n }\n }\n\n /// @notice Calculates arithmetic average of x and y, rounding down.\n /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n /// @return result The arithmetic average as a signed 59.18-decimal fixed-point number.\n function avg(int256 x, int256 y) internal pure returns (int256 result) {\n // The operations can never overflow.\n unchecked {\n // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n result = (x >> 1) + (y >> 1) + (x & y & 1);\n }\n }\n\n /// @notice Yields the least greatest signed 59.18 decimal fixed-point number greater than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be less than or equal to MAX_WHOLE_SD59x18.\n ///\n /// @param x The signed 59.18-decimal fixed-point number to ceil.\n /// @param result The least integer greater than or equal to x, as a signed 58.18-decimal fixed-point number.\n function ceil(int256 x) internal pure returns (int256 result) {\n require(x <= MAX_WHOLE_SD59x18);\n unchecked {\n int256 remainder = x % SCALE;\n if (remainder == 0) {\n result = x;\n } else {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n result = x - remainder;\n if (x > 0) {\n result += SCALE;\n }\n }\n }\n }\n\n /// @notice Divides two signed 59.18-decimal fixed-point numbers, returning a new signed 59.18-decimal fixed-point number.\n ///\n /// @dev Variant of \"mulDiv\" that works with signed numbers. Works by computing the signs and the absolute values separately.\n ///\n /// Requirements:\n /// - All from \"PRBMathCommon.mulDiv\".\n /// - None of the inputs can be type(int256).min.\n /// - y cannot be zero.\n /// - The result must fit within int256.\n ///\n /// Caveats:\n /// - All from \"PRBMathCommon.mulDiv\".\n ///\n /// @param x The numerator as a signed 59.18-decimal fixed-point number.\n /// @param y The denominator as a signed 59.18-decimal fixed-point number.\n /// @param result The quotient as a signed 59.18-decimal fixed-point number.\n function div(int256 x, int256 y) internal pure returns (int256 result) {\n require(x > type(int256).min);\n require(y > type(int256).min);\n\n // Get hold of the absolute values of x and y.\n uint256 ax;\n uint256 ay;\n unchecked {\n ax = x < 0 ? uint256(-x) : uint256(x);\n ay = y < 0 ? uint256(-y) : uint256(y);\n }\n\n // Compute the absolute value of (x*SCALE)\u00f7y. The result must fit within int256.\n uint256 resultUnsigned = PRBMathCommon.mulDiv(ax, uint256(SCALE), ay);\n require(resultUnsigned <= uint256(type(int256).max));\n\n // Get the signs of x and y.\n uint256 sx;\n uint256 sy;\n assembly {\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n }\n\n // XOR over sx and sy. This is basically checking whether the inputs have the same sign. If yes, the result\n // should be positive. Otherwise, it should be negative.\n result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n }\n\n /// @notice Returns Euler's number as a signed 59.18-decimal fixed-point number.\n /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n function e() internal pure returns (int256 result) {\n result = 2718281828459045235;\n }\n\n /// @notice Calculates the natural exponent of x.\n ///\n /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n ///\n /// Requirements:\n /// - All from \"log2\".\n /// - x must be less than 88722839111672999628.\n ///\n /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function exp(int256 x) internal pure returns (int256 result) {\n // Without this check, the value passed to \"exp2\" would be less than -59794705707972522261.\n if (x < -41446531673892822322) {\n return 0;\n }\n\n // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n require(x < 88722839111672999628);\n\n // Do the fixed-point multiplication inline to save gas.\n unchecked {\n int256 doubleScaleProduct = x * LOG2_E;\n result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n }\n }\n\n /// @notice Calculates the binary exponent of x using the binary fraction method.\n ///\n /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n ///\n /// Requirements:\n /// - x must be 128e18 or less.\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - For any x less than -59794705707972522261, the result is zero.\n ///\n /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function exp2(int256 x) internal pure returns (int256 result) {\n // This works because 2^(-x) = 1/2^x.\n if (x < 0) {\n // 2**59.794705707972522262 is the maximum number whose inverse does not turn into zero.\n if (x < -59794705707972522261) {\n return 0;\n }\n\n // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n unchecked { result = 1e36 / exp2(-x); }\n } else {\n // 2**128 doesn't fit within the 128.128-bit fixed-point representation.\n require(x < 128e18);\n\n unchecked {\n // Convert x to the 128.128-bit fixed-point format.\n uint256 x128x128 = (uint256(x) << 128) / uint256(SCALE);\n\n // Safe to convert the result to int256 directly because the maximum input allowed is 128e18.\n result = int256(PRBMathCommon.exp2(x128x128));\n }\n }\n }\n\n /// @notice Yields the greatest signed 59.18 decimal fixed-point number less than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be greater than or equal to MIN_WHOLE_SD59x18.\n ///\n /// @param x The signed 59.18-decimal fixed-point number to floor.\n /// @param result The greatest integer less than or equal to x, as a signed 58.18-decimal fixed-point number.\n function floor(int256 x) internal pure returns (int256 result) {\n require(x >= MIN_WHOLE_SD59x18);\n unchecked {\n int256 remainder = x % SCALE;\n if (remainder == 0) {\n result = x;\n } else {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n result = x - remainder;\n if (x < 0) {\n result -= SCALE;\n }\n }\n }\n }\n\n /// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right\n /// of the radix point for negative numbers.\n /// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n /// @param x The signed 59.18-decimal fixed-point number to get the fractional part of.\n /// @param result The fractional part of x as a signed 59.18-decimal fixed-point number.\n function frac(int256 x) internal pure returns (int256 result) {\n unchecked { result = x % SCALE; }\n }\n\n /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n ///\n /// @dev Requirements:\n /// - x * y must fit within MAX_SD59x18, lest it overflows.\n /// - x * y cannot be negative.\n ///\n /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function gm(int256 x, int256 y) internal pure returns (int256 result) {\n if (x == 0) {\n return 0;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n int256 xy = x * y;\n require(xy / x == y);\n\n // The product cannot be negative.\n require(xy >= 0);\n\n // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n // during multiplication. See the comments within the \"sqrt\" function.\n result = int256(PRBMathCommon.sqrt(uint256(xy)));\n }\n }\n\n /// @notice Calculates 1 / x, rounding towards zero.\n ///\n /// @dev Requirements:\n /// - x cannot be zero.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the inverse.\n /// @return result The inverse as a signed 59.18-decimal fixed-point number.\n function inv(int256 x) internal pure returns (int256 result) {\n unchecked {\n // 1e36 is SCALE * SCALE.\n result = 1e36 / x;\n }\n }\n\n /// @notice Calculates the natural logarithm of x.\n ///\n /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the natural logarithm.\n /// @return result The natural logarithm as a signed 59.18-decimal fixed-point number.\n function ln(int256 x) internal pure returns (int256 result) {\n // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n // can return is 195205294292027477728.\n unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n }\n\n /// @notice Calculates the common logarithm of x.\n ///\n /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the common logarithm.\n /// @return result The common logarithm as a signed 59.18-decimal fixed-point number.\n function log10(int256 x) internal pure returns (int256 result) {\n require(x > 0);\n\n // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n // prettier-ignore\n assembly {\n switch x\n case 1 { result := mul(SCALE, sub(0, 18)) }\n case 10 { result := mul(SCALE, sub(1, 18)) }\n case 100 { result := mul(SCALE, sub(2, 18)) }\n case 1000 { result := mul(SCALE, sub(3, 18)) }\n case 10000 { result := mul(SCALE, sub(4, 18)) }\n case 100000 { result := mul(SCALE, sub(5, 18)) }\n case 1000000 { result := mul(SCALE, sub(6, 18)) }\n case 10000000 { result := mul(SCALE, sub(7, 18)) }\n case 100000000 { result := mul(SCALE, sub(8, 18)) }\n case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := SCALE }\n case 100000000000000000000 { result := mul(SCALE, 2) }\n case 1000000000000000000000 { result := mul(SCALE, 3) }\n case 10000000000000000000000 { result := mul(SCALE, 4) }\n case 100000000000000000000000 { result := mul(SCALE, 5) }\n case 1000000000000000000000000 { result := mul(SCALE, 6) }\n case 10000000000000000000000000 { result := mul(SCALE, 7) }\n case 100000000000000000000000000 { result := mul(SCALE, 8) }\n case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n default {\n result := MAX_SD59x18\n }\n }\n\n if (result == MAX_SD59x18) {\n // Do the fixed-point division inline to save gas. The denominator is log2(10).\n unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n }\n }\n\n /// @notice Calculates the binary logarithm of x.\n ///\n /// @dev Based on the iterative approximation algorithm.\n /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n ///\n /// Requirements:\n /// - x must be greater than zero.\n ///\n /// Caveats:\n /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm.\n /// @return result The binary logarithm as a signed 59.18-decimal fixed-point number.\n function log2(int256 x) internal pure returns (int256 result) {\n require(x > 0);\n unchecked {\n // This works because log2(x) = -log2(1/x).\n int256 sign;\n if (x >= SCALE) {\n sign = 1;\n } else {\n sign = -1;\n // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n assembly {\n x := div(1000000000000000000000000000000000000, x)\n }\n }\n\n // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n uint256 n = PRBMathCommon.mostSignificantBit(uint256(x / SCALE));\n\n // The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow\n // because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1.\n result = int256(n) * SCALE;\n\n // This is y = x * 2^(-n).\n int256 y = x >> n;\n\n // If y = 1, the fractional part is zero.\n if (y == SCALE) {\n return result * sign;\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n for (int256 delta = int256(HALF_SCALE); delta > 0; delta >>= 1) {\n y = (y * y) / SCALE;\n\n // Is y^2 > 2 and so in the range [2,4)?\n if (y >= 2 * SCALE) {\n // Add the 2^(-m) factor to the logarithm.\n result += delta;\n\n // Corresponds to z/2 on Wikipedia.\n y >>= 1;\n }\n }\n result *= sign;\n }\n }\n\n /// @notice Multiplies two signed 59.18-decimal fixed-point numbers together, returning a new signed 59.18-decimal\n /// fixed-point number.\n ///\n /// @dev Variant of \"mulDiv\" that works with signed numbers and employs constant folding, i.e. the denominator is\n /// alawys 1e18.\n ///\n /// Requirements:\n /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - The body is purposely left uncommented; see the NatSpec comments in \"PRBMathCommon.mulDiv\" to understand how this works.\n ///\n /// @param x The multiplicand as a signed 59.18-decimal fixed-point number.\n /// @param y The multiplier as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function mul(int256 x, int256 y) internal pure returns (int256 result) {\n require(x > MIN_SD59x18);\n require(y > MIN_SD59x18);\n\n unchecked {\n uint256 ax;\n uint256 ay;\n ax = x < 0 ? uint256(-x) : uint256(x);\n ay = y < 0 ? uint256(-y) : uint256(y);\n\n uint256 resultUnsigned = PRBMathCommon.mulDivFixedPoint(ax, ay);\n require(resultUnsigned <= uint256(MAX_SD59x18));\n\n uint256 sx;\n uint256 sy;\n assembly {\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n }\n result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n }\n }\n\n /// @notice Retrieves PI as a signed 59.18-decimal fixed-point number.\n function pi() internal pure returns (int256 result) {\n result = 3141592653589793238;\n }\n\n /// @notice Raises x (signed 59.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n /// famous algorithm \"exponentiation by squaring\".\n ///\n /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n ///\n /// Requirements:\n /// - All from \"abs\" and \"PRBMathCommon.mulDivFixedPoint\".\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n /// - Assumes 0^0 is 1.\n ///\n /// @param x The base as a signed 59.18-decimal fixed-point number.\n /// @param y The exponent as an uint256.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function pow(int256 x, uint256 y) internal pure returns (int256 result) {\n uint256 absX = uint256(abs(x));\n\n // Calculate the first iteration of the loop in advance.\n uint256 absResult = y & 1 > 0 ? absX : uint256(SCALE);\n\n // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n for (y >>= 1; y > 0; y >>= 1) {\n absX = PRBMathCommon.mulDivFixedPoint(absX, absX);\n\n // Equivalent to \"y % 2 == 1\" but faster.\n if (y & 1 > 0) {\n absResult = PRBMathCommon.mulDivFixedPoint(absResult, absX);\n }\n }\n\n // The result must fit within the 59.18-decimal fixed-point representation.\n require(absResult <= uint256(MAX_SD59x18));\n\n // Is the base negative and the exponent an odd number?\n bool isNegative = x < 0 && y & 1 == 1;\n result = isNegative ? -int256(absResult) : int256(absResult);\n }\n\n /// @notice Returns 1 as a signed 59.18-decimal fixed-point number.\n function scale() internal pure returns (int256 result) {\n result = SCALE;\n }\n\n /// @notice Calculates the square root of x, rounding down.\n /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n ///\n /// Requirements:\n /// - x cannot be negative.\n /// - x must be less than MAX_SD59x18 / SCALE.\n ///\n /// Caveats:\n /// - The maximum fixed-point number permitted is 57896044618658097711785492504343953926634.992332820282019729.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the square root.\n /// @return result The result as a signed 59.18-decimal fixed-point .\n function sqrt(int256 x) internal pure returns (int256 result) {\n require(x >= 0);\n require(x < 57896044618658097711785492504343953926634992332820282019729);\n unchecked {\n // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two signed\n // 59.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n result = int256(PRBMathCommon.sqrt(uint256(x * SCALE)));\n }\n }\n}\n" + }, + "PRBMathUD60x18.sol": { + "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathUD60x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with uint256 numbers considered to have 18\n/// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60\n/// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the\n/// maximum values permitted by the Solidity type uint256.\nlibrary PRBMathUD60x18 {\n /// @dev Half the SCALE number.\n uint256 internal constant HALF_SCALE = 5e17;\n\n /// @dev log2(e) as an unsigned 60.18-decimal fixed-point number.\n uint256 internal constant LOG2_E = 1442695040888963407;\n\n /// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have.\n uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n /// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have.\n uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000;\n\n /// @dev How many trailing decimals can be represented.\n uint256 internal constant SCALE = 1e18;\n\n /// @notice Calculates arithmetic average of x and y, rounding down.\n /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.\n /// @return result The arithmetic average as an unsigned 60.18-decimal fixed-point number.\n function avg(uint256 x, uint256 y) internal pure returns (uint256 result) {\n // The operations can never overflow.\n unchecked {\n // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n result = (x >> 1) + (y >> 1) + (x & y & 1);\n }\n }\n\n /// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be less than or equal to MAX_WHOLE_UD60x18.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number to ceil.\n /// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number.\n function ceil(uint256 x) internal pure returns (uint256 result) {\n require(x <= MAX_WHOLE_UD60x18);\n assembly {\n // Equivalent to \"x % SCALE\" but faster.\n let remainder := mod(x, SCALE)\n\n // Equivalent to \"SCALE - remainder\" but faster.\n let delta := sub(SCALE, remainder)\n\n // Equivalent to \"x + delta * (remainder > 0 ? 1 : 0)\" but faster.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n }\n\n /// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number.\n ///\n /// @dev Uses mulDiv to enable overflow-safe multiplication and division.\n ///\n /// Requirements:\n /// - y cannot be zero.\n ///\n /// @param x The numerator as an unsigned 60.18-decimal fixed-point number.\n /// @param y The denominator as an unsigned 60.18-decimal fixed-point number.\n /// @param result The quotient as an unsigned 60.18-decimal fixed-point number.\n function div(uint256 x, uint256 y) internal pure returns (uint256 result) {\n result = PRBMathCommon.mulDiv(x, SCALE, y);\n }\n\n /// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number.\n /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n function e() internal pure returns (uint256 result) {\n result = 2718281828459045235;\n }\n\n /// @notice Calculates the natural exponent of x.\n ///\n /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n ///\n /// Requirements:\n /// - All from \"log2\".\n /// - x must be less than 88722839111672999628.\n ///\n /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function exp(uint256 x) internal pure returns (uint256 result) {\n // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n require(x < 88722839111672999628);\n\n // Do the fixed-point multiplication inline to save gas.\n unchecked {\n uint256 doubleScaleProduct = x * LOG2_E;\n result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n }\n }\n\n /// @notice Calculates the binary exponent of x using the binary fraction method.\n ///\n /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n ///\n /// Requirements:\n /// - x must be 128e18 or less.\n /// - The result must fit within MAX_UD60x18.\n ///\n /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function exp2(uint256 x) internal pure returns (uint256 result) {\n // 2**128 doesn't fit within the 128.128-bit format used internally in this function.\n require(x < 128e18);\n\n unchecked {\n // Convert x to the 128.128-bit fixed-point format.\n uint256 x128x128 = (x << 128) / SCALE;\n\n // Pass x to the PRBMathCommon.exp2 function, which uses the 128.128-bit fixed-point number representation.\n result = PRBMathCommon.exp2(x128x128);\n }\n }\n\n /// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x.\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n /// @param x The unsigned 60.18-decimal fixed-point number to floor.\n /// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number.\n function floor(uint256 x) internal pure returns (uint256 result) {\n assembly {\n // Equivalent to \"x % SCALE\" but faster.\n let remainder := mod(x, SCALE)\n\n // Equivalent to \"x - remainder * (remainder > 0 ? 1 : 0)\" but faster.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n }\n\n /// @notice Yields the excess beyond the floor of x.\n /// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part.\n /// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of.\n /// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number.\n function frac(uint256 x) internal pure returns (uint256 result) {\n assembly {\n result := mod(x, SCALE)\n }\n }\n\n /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n ///\n /// @dev Requirements:\n /// - x * y must fit within MAX_UD60x18, lest it overflows.\n ///\n /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function gm(uint256 x, uint256 y) internal pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xy = x * y;\n require(xy / x == y);\n\n // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n // during multiplication. See the comments within the \"sqrt\" function.\n result = PRBMathCommon.sqrt(xy);\n }\n }\n\n /// @notice Calculates 1 / x, rounding towards zero.\n ///\n /// @dev Requirements:\n /// - x cannot be zero.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse.\n /// @return result The inverse as an unsigned 60.18-decimal fixed-point number.\n function inv(uint256 x) internal pure returns (uint256 result) {\n unchecked {\n // 1e36 is SCALE * SCALE.\n result = 1e36 / x;\n }\n }\n\n /// @notice Calculates the natural logarithm of x.\n ///\n /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm.\n /// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number.\n function ln(uint256 x) internal pure returns (uint256 result) {\n // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n // can return is 196205294292027477728.\n unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n }\n\n /// @notice Calculates the common logarithm of x.\n ///\n /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm.\n /// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number.\n function log10(uint256 x) internal pure returns (uint256 result) {\n require(x >= SCALE);\n\n // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n // prettier-ignore\n assembly {\n switch x\n case 1 { result := mul(SCALE, sub(0, 18)) }\n case 10 { result := mul(SCALE, sub(1, 18)) }\n case 100 { result := mul(SCALE, sub(2, 18)) }\n case 1000 { result := mul(SCALE, sub(3, 18)) }\n case 10000 { result := mul(SCALE, sub(4, 18)) }\n case 100000 { result := mul(SCALE, sub(5, 18)) }\n case 1000000 { result := mul(SCALE, sub(6, 18)) }\n case 10000000 { result := mul(SCALE, sub(7, 18)) }\n case 100000000 { result := mul(SCALE, sub(8, 18)) }\n case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := SCALE }\n case 100000000000000000000 { result := mul(SCALE, 2) }\n case 1000000000000000000000 { result := mul(SCALE, 3) }\n case 10000000000000000000000 { result := mul(SCALE, 4) }\n case 100000000000000000000000 { result := mul(SCALE, 5) }\n case 1000000000000000000000000 { result := mul(SCALE, 6) }\n case 10000000000000000000000000 { result := mul(SCALE, 7) }\n case 100000000000000000000000000 { result := mul(SCALE, 8) }\n case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) }\n default {\n result := MAX_UD60x18\n }\n }\n\n if (result == MAX_UD60x18) {\n // Do the fixed-point division inline to save gas. The denominator is log2(10).\n unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n }\n }\n\n /// @notice Calculates the binary logarithm of x.\n ///\n /// @dev Based on the iterative approximation algorithm.\n /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n ///\n /// Requirements:\n /// - x must be greater than or equal to SCALE, otherwise the result would be negative.\n ///\n /// Caveats:\n /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm.\n /// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number.\n function log2(uint256 x) internal pure returns (uint256 result) {\n require(x >= SCALE);\n unchecked {\n // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n uint256 n = PRBMathCommon.mostSignificantBit(x / SCALE);\n\n // The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow\n // because n is maximum 255 and SCALE is 1e18.\n result = n * SCALE;\n\n // This is y = x * 2^(-n).\n uint256 y = x >> n;\n\n // If y = 1, the fractional part is zero.\n if (y == SCALE) {\n return result;\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) {\n y = (y * y) / SCALE;\n\n // Is y^2 > 2 and so in the range [2,4)?\n if (y >= 2 * SCALE) {\n // Add the 2^(-m) factor to the logarithm.\n result += delta;\n\n // Corresponds to z/2 on Wikipedia.\n y >>= 1;\n }\n }\n }\n }\n\n /// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal\n /// fixed-point number.\n /// @dev See the documentation for the \"PRBMathCommon.mulDivFixedPoint\" function.\n /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function mul(uint256 x, uint256 y) internal pure returns (uint256 result) {\n result = PRBMathCommon.mulDivFixedPoint(x, y);\n }\n\n /// @notice Retrieves PI as an unsigned 60.18-decimal fixed-point number.\n function pi() internal pure returns (uint256 result) {\n result = 3141592653589793238;\n }\n\n /// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n /// famous algorithm \"exponentiation by squaring\".\n ///\n /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n ///\n /// Requirements:\n /// - The result must fit within MAX_UD60x18.\n ///\n /// Caveats:\n /// - All from \"mul\".\n /// - Assumes 0^0 is 1.\n ///\n /// @param x The base as an unsigned 60.18-decimal fixed-point number.\n /// @param y The exponent as an uint256.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function pow(uint256 x, uint256 y) internal pure returns (uint256 result) {\n // Calculate the first iteration of the loop in advance.\n result = y & 1 > 0 ? x : SCALE;\n\n // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n for (y >>= 1; y > 0; y >>= 1) {\n x = PRBMathCommon.mulDivFixedPoint(x, x);\n\n // Equivalent to \"y % 2 == 1\" but faster.\n if (y & 1 > 0) {\n result = PRBMathCommon.mulDivFixedPoint(result, x);\n }\n }\n }\n\n /// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number.\n function scale() internal pure returns (uint256 result) {\n result = SCALE;\n }\n\n /// @notice Calculates the square root of x, rounding down.\n /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n ///\n /// Requirements:\n /// - x must be less than MAX_UD60x18 / SCALE.\n ///\n /// Caveats:\n /// - The maximum fixed-point number permitted is 115792089237316195423570985008687907853269.984665640564039458.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root.\n /// @return result The result as an unsigned 60.18-decimal fixed-point .\n function sqrt(uint256 x) internal pure returns (uint256 result) {\n require(x < 115792089237316195423570985008687907853269984665640564039458);\n unchecked {\n // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned\n // 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n result = PRBMathCommon.sqrt(x * SCALE);\n }\n }\n}\n" + }, + "PRBMathCommon.sol": { + "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\n/// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library\n/// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point\n// representation. When it does not, it is annotated in the function's NatSpec documentation.\nlibrary PRBMathCommon {\n /// @dev How many trailing decimals can be represented.\n uint256 internal constant SCALE = 1e18;\n\n /// @dev Largest power of two divisor of SCALE.\n uint256 internal constant SCALE_LPOTD = 262144;\n\n /// @dev SCALE inverted mod 2^256.\n uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661508869554232690281;\n\n /// @notice Calculates the binary exponent of x using the binary fraction method.\n /// @dev Uses 128.128-bit fixed-point numbers, which is the most efficient way.\n /// See https://ethereum.stackexchange.com/a/96594/24693.\n /// @param x The exponent as an unsigned 128.128-bit fixed-point number.\n /// @return result The result as an unsigned 60x18 decimal fixed-point number.\n function exp2(uint256 x) internal pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 128.128-bit fixed-point format.\n result = 0x80000000000000000000000000000000;\n\n // Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows\n // because the initial result is 2^127 and all magic factors are less than 2^129.\n if (x & 0x80000000000000000000000000000000 > 0) result = (result * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128;\n if (x & 0x40000000000000000000000000000000 > 0) result = (result * 0x1306FE0A31B7152DE8D5A46305C85EDED) >> 128;\n if (x & 0x20000000000000000000000000000000 > 0) result = (result * 0x1172B83C7D517ADCDF7C8C50EB14A7920) >> 128;\n if (x & 0x10000000000000000000000000000000 > 0) result = (result * 0x10B5586CF9890F6298B92B71842A98364) >> 128;\n if (x & 0x8000000000000000000000000000000 > 0) result = (result * 0x1059B0D31585743AE7C548EB68CA417FE) >> 128;\n if (x & 0x4000000000000000000000000000000 > 0) result = (result * 0x102C9A3E778060EE6F7CACA4F7A29BDE9) >> 128;\n if (x & 0x2000000000000000000000000000000 > 0) result = (result * 0x10163DA9FB33356D84A66AE336DCDFA40) >> 128;\n if (x & 0x1000000000000000000000000000000 > 0) result = (result * 0x100B1AFA5ABCBED6129AB13EC11DC9544) >> 128;\n if (x & 0x800000000000000000000000000000 > 0) result = (result * 0x10058C86DA1C09EA1FF19D294CF2F679C) >> 128;\n if (x & 0x400000000000000000000000000000 > 0) result = (result * 0x1002C605E2E8CEC506D21BFC89A23A011) >> 128;\n if (x & 0x200000000000000000000000000000 > 0) result = (result * 0x100162F3904051FA128BCA9C55C31E5E0) >> 128;\n if (x & 0x100000000000000000000000000000 > 0) result = (result * 0x1000B175EFFDC76BA38E31671CA939726) >> 128;\n if (x & 0x80000000000000000000000000000 > 0) result = (result * 0x100058BA01FB9F96D6CACD4B180917C3E) >> 128;\n if (x & 0x40000000000000000000000000000 > 0) result = (result * 0x10002C5CC37DA9491D0985C348C68E7B4) >> 128;\n if (x & 0x20000000000000000000000000000 > 0) result = (result * 0x1000162E525EE054754457D5995292027) >> 128;\n if (x & 0x10000000000000000000000000000 > 0) result = (result * 0x10000B17255775C040618BF4A4ADE83FD) >> 128;\n if (x & 0x8000000000000000000000000000 > 0) result = (result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAC) >> 128;\n if (x & 0x4000000000000000000000000000 > 0) result = (result * 0x100002C5C89D5EC6CA4D7C8ACC017B7CA) >> 128;\n if (x & 0x2000000000000000000000000000 > 0) result = (result * 0x10000162E43F4F831060E02D839A9D16D) >> 128;\n if (x & 0x1000000000000000000000000000 > 0) result = (result * 0x100000B1721BCFC99D9F890EA06911763) >> 128;\n if (x & 0x800000000000000000000000000 > 0) result = (result * 0x10000058B90CF1E6D97F9CA14DBCC1629) >> 128;\n if (x & 0x400000000000000000000000000 > 0) result = (result * 0x1000002C5C863B73F016468F6BAC5CA2C) >> 128;\n if (x & 0x200000000000000000000000000 > 0) result = (result * 0x100000162E430E5A18F6119E3C02282A6) >> 128;\n if (x & 0x100000000000000000000000000 > 0) result = (result * 0x1000000B1721835514B86E6D96EFD1BFF) >> 128;\n if (x & 0x80000000000000000000000000 > 0) result = (result * 0x100000058B90C0B48C6BE5DF846C5B2F0) >> 128;\n if (x & 0x40000000000000000000000000 > 0) result = (result * 0x10000002C5C8601CC6B9E94213C72737B) >> 128;\n if (x & 0x20000000000000000000000000 > 0) result = (result * 0x1000000162E42FFF037DF38AA2B219F07) >> 128;\n if (x & 0x10000000000000000000000000 > 0) result = (result * 0x10000000B17217FBA9C739AA5819F44FA) >> 128;\n if (x & 0x8000000000000000000000000 > 0) result = (result * 0x1000000058B90BFCDEE5ACD3C1CEDC824) >> 128;\n if (x & 0x4000000000000000000000000 > 0) result = (result * 0x100000002C5C85FE31F35A6A30DA1BE51) >> 128;\n if (x & 0x2000000000000000000000000 > 0) result = (result * 0x10000000162E42FF0999CE3541B9FFFD0) >> 128;\n if (x & 0x1000000000000000000000000 > 0) result = (result * 0x100000000B17217F80F4EF5AADDA45554) >> 128;\n if (x & 0x800000000000000000000000 > 0) result = (result * 0x10000000058B90BFBF8479BD5A81B51AE) >> 128;\n if (x & 0x400000000000000000000000 > 0) result = (result * 0x1000000002C5C85FDF84BD62AE30A74CD) >> 128;\n if (x & 0x200000000000000000000000 > 0) result = (result * 0x100000000162E42FEFB2FED257559BDAA) >> 128;\n if (x & 0x100000000000000000000000 > 0) result = (result * 0x1000000000B17217F7D5A7716BBA4A9AF) >> 128;\n if (x & 0x80000000000000000000000 > 0) result = (result * 0x100000000058B90BFBE9DDBAC5E109CCF) >> 128;\n if (x & 0x40000000000000000000000 > 0) result = (result * 0x10000000002C5C85FDF4B15DE6F17EB0E) >> 128;\n if (x & 0x20000000000000000000000 > 0) result = (result * 0x1000000000162E42FEFA494F1478FDE05) >> 128;\n if (x & 0x10000000000000000000000 > 0) result = (result * 0x10000000000B17217F7D20CF927C8E94D) >> 128;\n if (x & 0x8000000000000000000000 > 0) result = (result * 0x1000000000058B90BFBE8F71CB4E4B33E) >> 128;\n if (x & 0x4000000000000000000000 > 0) result = (result * 0x100000000002C5C85FDF477B662B26946) >> 128;\n if (x & 0x2000000000000000000000 > 0) result = (result * 0x10000000000162E42FEFA3AE53369388D) >> 128;\n if (x & 0x1000000000000000000000 > 0) result = (result * 0x100000000000B17217F7D1D351A389D41) >> 128;\n if (x & 0x800000000000000000000 > 0) result = (result * 0x10000000000058B90BFBE8E8B2D3D4EDF) >> 128;\n if (x & 0x400000000000000000000 > 0) result = (result * 0x1000000000002C5C85FDF4741BEA6E77F) >> 128;\n if (x & 0x200000000000000000000 > 0) result = (result * 0x100000000000162E42FEFA39FE95583C3) >> 128;\n if (x & 0x100000000000000000000 > 0) result = (result * 0x1000000000000B17217F7D1CFB72B45E3) >> 128;\n if (x & 0x80000000000000000000 > 0) result = (result * 0x100000000000058B90BFBE8E7CC35C3F2) >> 128;\n if (x & 0x40000000000000000000 > 0) result = (result * 0x10000000000002C5C85FDF473E242EA39) >> 128;\n if (x & 0x20000000000000000000 > 0) result = (result * 0x1000000000000162E42FEFA39F02B772C) >> 128;\n if (x & 0x10000000000000000000 > 0) result = (result * 0x10000000000000B17217F7D1CF7D83C1A) >> 128;\n if (x & 0x8000000000000000000 > 0) result = (result * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128;\n if (x & 0x4000000000000000000 > 0) result = (result * 0x100000000000002C5C85FDF473DEA871F) >> 128;\n if (x & 0x2000000000000000000 > 0) result = (result * 0x10000000000000162E42FEFA39EF44D92) >> 128;\n if (x & 0x1000000000000000000 > 0) result = (result * 0x100000000000000B17217F7D1CF79E949) >> 128;\n if (x & 0x800000000000000000 > 0) result = (result * 0x10000000000000058B90BFBE8E7BCE545) >> 128;\n if (x & 0x400000000000000000 > 0) result = (result * 0x1000000000000002C5C85FDF473DE6ECA) >> 128;\n if (x & 0x200000000000000000 > 0) result = (result * 0x100000000000000162E42FEFA39EF366F) >> 128;\n if (x & 0x100000000000000000 > 0) result = (result * 0x1000000000000000B17217F7D1CF79AFA) >> 128;\n if (x & 0x80000000000000000 > 0) result = (result * 0x100000000000000058B90BFBE8E7BCD6E) >> 128;\n if (x & 0x40000000000000000 > 0) result = (result * 0x10000000000000002C5C85FDF473DE6B3) >> 128;\n if (x & 0x20000000000000000 > 0) result = (result * 0x1000000000000000162E42FEFA39EF359) >> 128;\n if (x & 0x10000000000000000 > 0) result = (result * 0x10000000000000000B17217F7D1CF79AC) >> 128;\n\n // We do two things at the same time below:\n //\n // 1. Multiply the result by 2^n + 1, where 2^n is the integer part and 1 is an extra bit to account\n // for the fact that we initially set the result to 0.5 We implement this by subtracting from 127\n // instead of 128.\n // 2. Convert the result to the unsigned 60.18-decimal fixed-point format.\n //\n // This works because result * SCALE * 2^ip / 2^127 = result * SCALE / 2^(127 - ip), where ip is the integer\n // part and SCALE / 2^128 is what converts the result to our unsigned fixed-point format.\n result *= SCALE;\n result >>= (127 - (x >> 128));\n }\n }\n\n /// @notice Finds the zero-based index of the first one in the binary representation of x.\n /// @dev See the note on msb in the \"Find First Set\" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set\n /// @param x The uint256 number for which to find the index of the most significant bit.\n /// @return msb The index of the most significant bit as an uint256.\n function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) {\n if (x >= 2**128) {\n x >>= 128;\n msb += 128;\n }\n if (x >= 2**64) {\n x >>= 64;\n msb += 64;\n }\n if (x >= 2**32) {\n x >>= 32;\n msb += 32;\n }\n if (x >= 2**16) {\n x >>= 16;\n msb += 16;\n }\n if (x >= 2**8) {\n x >>= 8;\n msb += 8;\n }\n if (x >= 2**4) {\n x >>= 4;\n msb += 4;\n }\n if (x >= 2**2) {\n x >>= 2;\n msb += 2;\n }\n if (x >= 2**1) {\n // No need to shift x any more.\n msb += 1;\n }\n }\n\n /// @notice Calculates floor(x*y\u00f7denominator) with full precision.\n ///\n /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n ///\n /// Requirements:\n /// - The denominator cannot be zero.\n /// - The result must fit within uint256.\n ///\n /// Caveats:\n /// - This function does not work with fixed-point numbers.\n ///\n /// @param x The multiplicand as an uint256.\n /// @param y The multiplier as an uint256.\n /// @param denominator The divisor as an uint256.\n /// @return result The result as an uint256.\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2**256 and mod 2**256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2**256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division\n if (prod1 == 0) {\n require(denominator > 0);\n assembly {\n result := div(prod0, denominator)\n }\n return result;\n }\n\n // Make sure the result is less than 2**256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n unchecked {\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 lpotdod = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by lpotdod.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Flip lpotdod such that it is 2**256 / lpotdod. If lpotdod is zero, then it becomes one.\n lpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * lpotdod;\n\n // Invert denominator mod 2**256. Now that denominator is an odd number, it has an inverse modulo 2**256 such\n // that denominator * inv = 1 mod 2**256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2**4\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Now use Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2**8\n inverse *= 2 - denominator * inverse; // inverse mod 2**16\n inverse *= 2 - denominator * inverse; // inverse mod 2**32\n inverse *= 2 - denominator * inverse; // inverse mod 2**64\n inverse *= 2 - denominator * inverse; // inverse mod 2**128\n inverse *= 2 - denominator * inverse; // inverse mod 2**256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2**256. Since the precoditions guarantee that the outcome is\n // less than 2**256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /// @notice Calculates floor(x*y\u00f71e18) with full precision.\n ///\n /// @dev Variant of \"mulDiv\" with constant folding, i.e. in which the denominator is always 1e18. Before returning the\n /// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of\n /// being rounded to 1e-18. See \"Listing 6\" and text above it at https://accu.org/index.php/journals/1717.\n ///\n /// Requirements:\n /// - The result must fit within uint256.\n ///\n /// Caveats:\n /// - The body is purposely left uncommented; see the NatSpec comments in \"PRBMathCommon.mulDiv\" to understand how this works.\n /// - It is assumed that the result can never be type(uint256).max when x and y solve the following two equations:\n /// 1. x * y = type(uint256).max * SCALE\n /// 2. (x * y) % SCALE >= SCALE / 2\n ///\n /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n uint256 remainder;\n uint256 roundUpUnit;\n assembly {\n remainder := mulmod(x, y, SCALE)\n roundUpUnit := gt(remainder, 499999999999999999)\n }\n\n if (prod1 == 0) {\n unchecked {\n result = (prod0 / SCALE) + roundUpUnit;\n return result;\n }\n }\n\n require(SCALE > prod1);\n\n assembly {\n result := add(\n mul(\n or(\n div(sub(prod0, remainder), SCALE_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1))\n ),\n SCALE_INVERSE\n ),\n roundUpUnit\n )\n }\n }\n\n /// @notice Calculates the square root of x, rounding down.\n /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n ///\n /// Caveats:\n /// - This function does not work with fixed-point numbers.\n ///\n /// @param x The uint256 number for which to calculate the square root.\n /// @return result The result as an uint256.\n function sqrt(uint256 x) internal pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // Calculate the square root of the perfect square of a power of two that is the closest to x.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 0x100000000000000000000000000000000) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 0x10000000000000000) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 0x100000000) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 0x10000) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 0x100) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 0x10) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 0x8) {\n result <<= 1;\n }\n\n // The operations can never overflow because the result is max 2^127 when it enters this block.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1; // Seven iterations should be enough\n uint256 roundedDownResult = x / result;\n return result >= roundedDownResult ? roundedDownResult : result;\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18.sol b/examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18.sol new file mode 100644 index 00000000..9f3a1094 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18.sol @@ -0,0 +1,578 @@ +// SPDX-License-Identifier: WTFPL +pragma solidity >=0.8.0; + +import "./PRBMathCommon.sol"; + +/// @title PRBMathSD59x18 +/// @author Paul Razvan Berg +/// @notice Smart contract library for advanced fixed-point math. It works with int256 numbers considered to have 18 +/// trailing decimals. We call this number representation signed 59.18-decimal fixed-point, since the numbers can have +/// a sign and there can be up to 59 digits in the integer part and up to 18 decimals in the fractional part. The numbers +/// are bound by the minimum and the maximum values permitted by the Solidity type int256. +library PRBMathSD59x18 { + /// @dev log2(e) as a signed 59.18-decimal fixed-point number. + int256 internal constant LOG2_E = 1442695040888963407; + + /// @dev Half the SCALE number. + int256 internal constant HALF_SCALE = 5e17; + + /// @dev The maximum value a signed 59.18-decimal fixed-point number can have. + int256 internal constant MAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728792003956564819967; + + /// @dev The maximum whole value a signed 59.18-decimal fixed-point number can have. + int256 internal constant MAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728000000000000000000; + + /// @dev The minimum value a signed 59.18-decimal fixed-point number can have. + int256 internal constant MIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + + /// @dev The minimum whole value a signed 59.18-decimal fixed-point number can have. + int256 internal constant MIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728000000000000000000; + + /// @dev How many trailing decimals can be represented. + int256 internal constant SCALE = 1e18; + + /// INTERNAL FUNCTIONS /// + + /// @notice Calculate the absolute value of x. + /// + /// @dev Requirements: + /// - x must be greater than MIN_SD59x18. + /// + /// @param x The number to calculate the absolute value for. + /// @param result The absolute value of x. + function abs(int256 x) internal pure returns (int256 result) { + unchecked { + require(x > MIN_SD59x18); + result = x < 0 ? -x : x; + } + } + + /// @notice Calculates arithmetic average of x and y, rounding down. + /// @param x The first operand as a signed 59.18-decimal fixed-point number. + /// @param y The second operand as a signed 59.18-decimal fixed-point number. + /// @return result The arithmetic average as a signed 59.18-decimal fixed-point number. + function avg(int256 x, int256 y) internal pure returns (int256 result) { + // The operations can never overflow. + unchecked { + // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need + // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice. + result = (x >> 1) + (y >> 1) + (x & y & 1); + } + } + + /// @notice Yields the least greatest signed 59.18 decimal fixed-point number greater than or equal to x. + /// + /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts. + /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions. + /// + /// Requirements: + /// - x must be less than or equal to MAX_WHOLE_SD59x18. + /// + /// @param x The signed 59.18-decimal fixed-point number to ceil. + /// @param result The least integer greater than or equal to x, as a signed 58.18-decimal fixed-point number. + function ceil(int256 x) internal pure returns (int256 result) { + require(x <= MAX_WHOLE_SD59x18); + unchecked { + int256 remainder = x % SCALE; + if (remainder == 0) { + result = x; + } else { + // Solidity uses C fmod style, which returns a modulus with the same sign as x. + result = x - remainder; + if (x > 0) { + result += SCALE; + } + } + } + } + + /// @notice Divides two signed 59.18-decimal fixed-point numbers, returning a new signed 59.18-decimal fixed-point number. + /// + /// @dev Variant of "mulDiv" that works with signed numbers. Works by computing the signs and the absolute values separately. + /// + /// Requirements: + /// - All from "PRBMathCommon.mulDiv". + /// - None of the inputs can be type(int256).min. + /// - y cannot be zero. + /// - The result must fit within int256. + /// + /// Caveats: + /// - All from "PRBMathCommon.mulDiv". + /// + /// @param x The numerator as a signed 59.18-decimal fixed-point number. + /// @param y The denominator as a signed 59.18-decimal fixed-point number. + /// @param result The quotient as a signed 59.18-decimal fixed-point number. + function div(int256 x, int256 y) internal pure returns (int256 result) { + require(x > type(int256).min); + require(y > type(int256).min); + + // Get hold of the absolute values of x and y. + uint256 ax; + uint256 ay; + unchecked { + ax = x < 0 ? uint256(-x) : uint256(x); + ay = y < 0 ? uint256(-y) : uint256(y); + } + + // Compute the absolute value of (x*SCALE)÷y. The result must fit within int256. + uint256 resultUnsigned = PRBMathCommon.mulDiv(ax, uint256(SCALE), ay); + require(resultUnsigned <= uint256(type(int256).max)); + + // Get the signs of x and y. + uint256 sx; + uint256 sy; + assembly { + sx := sgt(x, sub(0, 1)) + sy := sgt(y, sub(0, 1)) + } + + // XOR over sx and sy. This is basically checking whether the inputs have the same sign. If yes, the result + // should be positive. Otherwise, it should be negative. + result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned); + } + + /// @notice Returns Euler's number as a signed 59.18-decimal fixed-point number. + /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant). + function e() internal pure returns (int256 result) { + result = 2718281828459045235; + } + + /// @notice Calculates the natural exponent of x. + /// + /// @dev Based on the insight that e^x = 2^(x * log2(e)). + /// + /// Requirements: + /// - All from "log2". + /// - x must be less than 88722839111672999628. + /// + /// @param x The exponent as a signed 59.18-decimal fixed-point number. + /// @return result The result as a signed 59.18-decimal fixed-point number. + function exp(int256 x) internal pure returns (int256 result) { + // Without this check, the value passed to "exp2" would be less than -59794705707972522261. + if (x < -41446531673892822322) { + return 0; + } + + // Without this check, the value passed to "exp2" would be greater than 128e18. + require(x < 88722839111672999628); + + // Do the fixed-point multiplication inline to save gas. + unchecked { + int256 doubleScaleProduct = x * LOG2_E; + result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE); + } + } + + /// @notice Calculates the binary exponent of x using the binary fraction method. + /// + /// @dev See https://ethereum.stackexchange.com/q/79903/24693. + /// + /// Requirements: + /// - x must be 128e18 or less. + /// - The result must fit within MAX_SD59x18. + /// + /// Caveats: + /// - For any x less than -59794705707972522261, the result is zero. + /// + /// @param x The exponent as a signed 59.18-decimal fixed-point number. + /// @return result The result as a signed 59.18-decimal fixed-point number. + function exp2(int256 x) internal pure returns (int256 result) { + // This works because 2^(-x) = 1/2^x. + if (x < 0) { + // 2**59.794705707972522262 is the maximum number whose inverse does not turn into zero. + if (x < -59794705707972522261) { + return 0; + } + + // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE. + unchecked { result = 1e36 / exp2(-x); } + } else { + // 2**128 doesn't fit within the 128.128-bit fixed-point representation. + require(x < 128e18); + + unchecked { + // Convert x to the 128.128-bit fixed-point format. + uint256 x128x128 = (uint256(x) << 128) / uint256(SCALE); + + // Safe to convert the result to int256 directly because the maximum input allowed is 128e18. + result = int256(PRBMathCommon.exp2(x128x128)); + } + } + } + + /// @notice Yields the greatest signed 59.18 decimal fixed-point number less than or equal to x. + /// + /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts. + /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions. + /// + /// Requirements: + /// - x must be greater than or equal to MIN_WHOLE_SD59x18. + /// + /// @param x The signed 59.18-decimal fixed-point number to floor. + /// @param result The greatest integer less than or equal to x, as a signed 58.18-decimal fixed-point number. + function floor(int256 x) internal pure returns (int256 result) { + require(x >= MIN_WHOLE_SD59x18); + unchecked { + int256 remainder = x % SCALE; + if (remainder == 0) { + result = x; + } else { + // Solidity uses C fmod style, which returns a modulus with the same sign as x. + result = x - remainder; + if (x < 0) { + result -= SCALE; + } + } + } + } + + /// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right + /// of the radix point for negative numbers. + /// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part + /// @param x The signed 59.18-decimal fixed-point number to get the fractional part of. + /// @param result The fractional part of x as a signed 59.18-decimal fixed-point number. + function frac(int256 x) internal pure returns (int256 result) { + unchecked { result = x % SCALE; } + } + + /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down. + /// + /// @dev Requirements: + /// - x * y must fit within MAX_SD59x18, lest it overflows. + /// - x * y cannot be negative. + /// + /// @param x The first operand as a signed 59.18-decimal fixed-point number. + /// @param y The second operand as a signed 59.18-decimal fixed-point number. + /// @return result The result as a signed 59.18-decimal fixed-point number. + function gm(int256 x, int256 y) internal pure returns (int256 result) { + if (x == 0) { + return 0; + } + + unchecked { + // Checking for overflow this way is faster than letting Solidity do it. + int256 xy = x * y; + require(xy / x == y); + + // The product cannot be negative. + require(xy >= 0); + + // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE + // during multiplication. See the comments within the "sqrt" function. + result = int256(PRBMathCommon.sqrt(uint256(xy))); + } + } + + /// @notice Calculates 1 / x, rounding towards zero. + /// + /// @dev Requirements: + /// - x cannot be zero. + /// + /// @param x The signed 59.18-decimal fixed-point number for which to calculate the inverse. + /// @return result The inverse as a signed 59.18-decimal fixed-point number. + function inv(int256 x) internal pure returns (int256 result) { + unchecked { + // 1e36 is SCALE * SCALE. + result = 1e36 / x; + } + } + + /// @notice Calculates the natural logarithm of x. + /// + /// @dev Based on the insight that ln(x) = log2(x) / log2(e). + /// + /// Requirements: + /// - All from "log2". + /// + /// Caveats: + /// - All from "log2". + /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision. + /// + /// @param x The signed 59.18-decimal fixed-point number for which to calculate the natural logarithm. + /// @return result The natural logarithm as a signed 59.18-decimal fixed-point number. + function ln(int256 x) internal pure returns (int256 result) { + // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x) + // can return is 195205294292027477728. + unchecked { result = (log2(x) * SCALE) / LOG2_E; } + } + + /// @notice Calculates the common logarithm of x. + /// + /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common + /// logarithm based on the insight that log10(x) = log2(x) / log2(10). + /// + /// Requirements: + /// - All from "log2". + /// + /// Caveats: + /// - All from "log2". + /// + /// @param x The signed 59.18-decimal fixed-point number for which to calculate the common logarithm. + /// @return result The common logarithm as a signed 59.18-decimal fixed-point number. + function log10(int256 x) internal pure returns (int256 result) { + require(x > 0); + + // Note that the "mul" in this block is the assembly mul operation, not the "mul" function defined in this contract. + // prettier-ignore + assembly { + switch x + case 1 { result := mul(SCALE, sub(0, 18)) } + case 10 { result := mul(SCALE, sub(1, 18)) } + case 100 { result := mul(SCALE, sub(2, 18)) } + case 1000 { result := mul(SCALE, sub(3, 18)) } + case 10000 { result := mul(SCALE, sub(4, 18)) } + case 100000 { result := mul(SCALE, sub(5, 18)) } + case 1000000 { result := mul(SCALE, sub(6, 18)) } + case 10000000 { result := mul(SCALE, sub(7, 18)) } + case 100000000 { result := mul(SCALE, sub(8, 18)) } + case 1000000000 { result := mul(SCALE, sub(9, 18)) } + case 10000000000 { result := mul(SCALE, sub(10, 18)) } + case 100000000000 { result := mul(SCALE, sub(11, 18)) } + case 1000000000000 { result := mul(SCALE, sub(12, 18)) } + case 10000000000000 { result := mul(SCALE, sub(13, 18)) } + case 100000000000000 { result := mul(SCALE, sub(14, 18)) } + case 1000000000000000 { result := mul(SCALE, sub(15, 18)) } + case 10000000000000000 { result := mul(SCALE, sub(16, 18)) } + case 100000000000000000 { result := mul(SCALE, sub(17, 18)) } + case 1000000000000000000 { result := 0 } + case 10000000000000000000 { result := SCALE } + case 100000000000000000000 { result := mul(SCALE, 2) } + case 1000000000000000000000 { result := mul(SCALE, 3) } + case 10000000000000000000000 { result := mul(SCALE, 4) } + case 100000000000000000000000 { result := mul(SCALE, 5) } + case 1000000000000000000000000 { result := mul(SCALE, 6) } + case 10000000000000000000000000 { result := mul(SCALE, 7) } + case 100000000000000000000000000 { result := mul(SCALE, 8) } + case 1000000000000000000000000000 { result := mul(SCALE, 9) } + case 10000000000000000000000000000 { result := mul(SCALE, 10) } + case 100000000000000000000000000000 { result := mul(SCALE, 11) } + case 1000000000000000000000000000000 { result := mul(SCALE, 12) } + case 10000000000000000000000000000000 { result := mul(SCALE, 13) } + case 100000000000000000000000000000000 { result := mul(SCALE, 14) } + case 1000000000000000000000000000000000 { result := mul(SCALE, 15) } + case 10000000000000000000000000000000000 { result := mul(SCALE, 16) } + case 100000000000000000000000000000000000 { result := mul(SCALE, 17) } + case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) } + case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) } + case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) } + case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) } + case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) } + case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) } + case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) } + case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) } + case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) } + case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) } + case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) } + case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) } + case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) } + case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) } + case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) } + case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) } + case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) } + case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) } + case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) } + case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) } + case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) } + case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) } + case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) } + case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) } + case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) } + case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) } + case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) } + case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) } + case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) } + case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) } + case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) } + case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) } + case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) } + case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) } + case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) } + case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) } + case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) } + case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) } + case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) } + case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) } + case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) } + default { + result := MAX_SD59x18 + } + } + + if (result == MAX_SD59x18) { + // Do the fixed-point division inline to save gas. The denominator is log2(10). + unchecked { result = (log2(x) * SCALE) / 332192809488736234; } + } + } + + /// @notice Calculates the binary logarithm of x. + /// + /// @dev Based on the iterative approximation algorithm. + /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation + /// + /// Requirements: + /// - x must be greater than zero. + /// + /// Caveats: + /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation. + /// + /// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm. + /// @return result The binary logarithm as a signed 59.18-decimal fixed-point number. + function log2(int256 x) internal pure returns (int256 result) { + require(x > 0); + unchecked { + // This works because log2(x) = -log2(1/x). + int256 sign; + if (x >= SCALE) { + sign = 1; + } else { + sign = -1; + // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE. + assembly { + x := div(1000000000000000000000000000000000000, x) + } + } + + // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n). + uint256 n = PRBMathCommon.mostSignificantBit(uint256(x / SCALE)); + + // The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow + // because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1. + result = int256(n) * SCALE; + + // This is y = x * 2^(-n). + int256 y = x >> n; + + // If y = 1, the fractional part is zero. + if (y == SCALE) { + return result * sign; + } + + // Calculate the fractional part via the iterative approximation. + // The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster. + for (int256 delta = int256(HALF_SCALE); delta > 0; delta >>= 1) { + y = (y * y) / SCALE; + + // Is y^2 > 2 and so in the range [2,4)? + if (y >= 2 * SCALE) { + // Add the 2^(-m) factor to the logarithm. + result += delta; + + // Corresponds to z/2 on Wikipedia. + y >>= 1; + } + } + result *= sign; + } + } + + /// @notice Multiplies two signed 59.18-decimal fixed-point numbers together, returning a new signed 59.18-decimal + /// fixed-point number. + /// + /// @dev Variant of "mulDiv" that works with signed numbers and employs constant folding, i.e. the denominator is + /// alawys 1e18. + /// + /// Requirements: + /// - All from "PRBMathCommon.mulDivFixedPoint". + /// - The result must fit within MAX_SD59x18. + /// + /// Caveats: + /// - The body is purposely left uncommented; see the NatSpec comments in "PRBMathCommon.mulDiv" to understand how this works. + /// + /// @param x The multiplicand as a signed 59.18-decimal fixed-point number. + /// @param y The multiplier as a signed 59.18-decimal fixed-point number. + /// @return result The result as a signed 59.18-decimal fixed-point number. + function mul(int256 x, int256 y) internal pure returns (int256 result) { + require(x > MIN_SD59x18); + require(y > MIN_SD59x18); + + unchecked { + uint256 ax; + uint256 ay; + ax = x < 0 ? uint256(-x) : uint256(x); + ay = y < 0 ? uint256(-y) : uint256(y); + + uint256 resultUnsigned = PRBMathCommon.mulDivFixedPoint(ax, ay); + require(resultUnsigned <= uint256(MAX_SD59x18)); + + uint256 sx; + uint256 sy; + assembly { + sx := sgt(x, sub(0, 1)) + sy := sgt(y, sub(0, 1)) + } + result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned); + } + } + + /// @notice Retrieves PI as a signed 59.18-decimal fixed-point number. + function pi() internal pure returns (int256 result) { + result = 3141592653589793238; + } + + /// @notice Raises x (signed 59.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the + /// famous algorithm "exponentiation by squaring". + /// + /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring + /// + /// Requirements: + /// - All from "abs" and "PRBMathCommon.mulDivFixedPoint". + /// - The result must fit within MAX_SD59x18. + /// + /// Caveats: + /// - All from "PRBMathCommon.mulDivFixedPoint". + /// - Assumes 0^0 is 1. + /// + /// @param x The base as a signed 59.18-decimal fixed-point number. + /// @param y The exponent as an uint256. + /// @return result The result as a signed 59.18-decimal fixed-point number. + function pow(int256 x, uint256 y) internal pure returns (int256 result) { + uint256 absX = uint256(abs(x)); + + // Calculate the first iteration of the loop in advance. + uint256 absResult = y & 1 > 0 ? absX : uint256(SCALE); + + // Equivalent to "for(y /= 2; y > 0; y /= 2)" but faster. + for (y >>= 1; y > 0; y >>= 1) { + absX = PRBMathCommon.mulDivFixedPoint(absX, absX); + + // Equivalent to "y % 2 == 1" but faster. + if (y & 1 > 0) { + absResult = PRBMathCommon.mulDivFixedPoint(absResult, absX); + } + } + + // The result must fit within the 59.18-decimal fixed-point representation. + require(absResult <= uint256(MAX_SD59x18)); + + // Is the base negative and the exponent an odd number? + bool isNegative = x < 0 && y & 1 == 1; + result = isNegative ? -int256(absResult) : int256(absResult); + } + + /// @notice Returns 1 as a signed 59.18-decimal fixed-point number. + function scale() internal pure returns (int256 result) { + result = SCALE; + } + + /// @notice Calculates the square root of x, rounding down. + /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method. + /// + /// Requirements: + /// - x cannot be negative. + /// - x must be less than MAX_SD59x18 / SCALE. + /// + /// Caveats: + /// - The maximum fixed-point number permitted is 57896044618658097711785492504343953926634.992332820282019729. + /// + /// @param x The signed 59.18-decimal fixed-point number for which to calculate the square root. + /// @return result The result as a signed 59.18-decimal fixed-point . + function sqrt(int256 x) internal pure returns (int256 result) { + require(x >= 0); + require(x < 57896044618658097711785492504343953926634992332820282019729); + unchecked { + // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two signed + // 59.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root). + result = int256(PRBMathCommon.sqrt(uint256(x * SCALE))); + } + } +} diff --git a/examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18_standard_input.json b/examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18_standard_input.json new file mode 100644 index 00000000..7307ec10 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__prbmath_PRBMathSD59x18/PRBMathSD59x18_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "PRBMathSD59x18.sol": { + "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathSD59x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with int256 numbers considered to have 18\n/// trailing decimals. We call this number representation signed 59.18-decimal fixed-point, since the numbers can have\n/// a sign and there can be up to 59 digits in the integer part and up to 18 decimals in the fractional part. The numbers\n/// are bound by the minimum and the maximum values permitted by the Solidity type int256.\nlibrary PRBMathSD59x18 {\n /// @dev log2(e) as a signed 59.18-decimal fixed-point number.\n int256 internal constant LOG2_E = 1442695040888963407;\n\n /// @dev Half the SCALE number.\n int256 internal constant HALF_SCALE = 5e17;\n\n /// @dev The maximum value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728792003956564819967;\n\n /// @dev The maximum whole value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n /// @dev The minimum value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n /// @dev The minimum whole value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n /// @dev How many trailing decimals can be represented.\n int256 internal constant SCALE = 1e18;\n\n /// INTERNAL FUNCTIONS ///\n\n /// @notice Calculate the absolute value of x.\n ///\n /// @dev Requirements:\n /// - x must be greater than MIN_SD59x18.\n ///\n /// @param x The number to calculate the absolute value for.\n /// @param result The absolute value of x.\n function abs(int256 x) internal pure returns (int256 result) {\n unchecked {\n require(x > MIN_SD59x18);\n result = x < 0 ? -x : x;\n }\n }\n\n /// @notice Calculates arithmetic average of x and y, rounding down.\n /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n /// @return result The arithmetic average as a signed 59.18-decimal fixed-point number.\n function avg(int256 x, int256 y) internal pure returns (int256 result) {\n // The operations can never overflow.\n unchecked {\n // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n result = (x >> 1) + (y >> 1) + (x & y & 1);\n }\n }\n\n /// @notice Yields the least greatest signed 59.18 decimal fixed-point number greater than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be less than or equal to MAX_WHOLE_SD59x18.\n ///\n /// @param x The signed 59.18-decimal fixed-point number to ceil.\n /// @param result The least integer greater than or equal to x, as a signed 58.18-decimal fixed-point number.\n function ceil(int256 x) internal pure returns (int256 result) {\n require(x <= MAX_WHOLE_SD59x18);\n unchecked {\n int256 remainder = x % SCALE;\n if (remainder == 0) {\n result = x;\n } else {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n result = x - remainder;\n if (x > 0) {\n result += SCALE;\n }\n }\n }\n }\n\n /// @notice Divides two signed 59.18-decimal fixed-point numbers, returning a new signed 59.18-decimal fixed-point number.\n ///\n /// @dev Variant of \"mulDiv\" that works with signed numbers. Works by computing the signs and the absolute values separately.\n ///\n /// Requirements:\n /// - All from \"PRBMathCommon.mulDiv\".\n /// - None of the inputs can be type(int256).min.\n /// - y cannot be zero.\n /// - The result must fit within int256.\n ///\n /// Caveats:\n /// - All from \"PRBMathCommon.mulDiv\".\n ///\n /// @param x The numerator as a signed 59.18-decimal fixed-point number.\n /// @param y The denominator as a signed 59.18-decimal fixed-point number.\n /// @param result The quotient as a signed 59.18-decimal fixed-point number.\n function div(int256 x, int256 y) internal pure returns (int256 result) {\n require(x > type(int256).min);\n require(y > type(int256).min);\n\n // Get hold of the absolute values of x and y.\n uint256 ax;\n uint256 ay;\n unchecked {\n ax = x < 0 ? uint256(-x) : uint256(x);\n ay = y < 0 ? uint256(-y) : uint256(y);\n }\n\n // Compute the absolute value of (x*SCALE)\u00f7y. The result must fit within int256.\n uint256 resultUnsigned = PRBMathCommon.mulDiv(ax, uint256(SCALE), ay);\n require(resultUnsigned <= uint256(type(int256).max));\n\n // Get the signs of x and y.\n uint256 sx;\n uint256 sy;\n assembly {\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n }\n\n // XOR over sx and sy. This is basically checking whether the inputs have the same sign. If yes, the result\n // should be positive. Otherwise, it should be negative.\n result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n }\n\n /// @notice Returns Euler's number as a signed 59.18-decimal fixed-point number.\n /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n function e() internal pure returns (int256 result) {\n result = 2718281828459045235;\n }\n\n /// @notice Calculates the natural exponent of x.\n ///\n /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n ///\n /// Requirements:\n /// - All from \"log2\".\n /// - x must be less than 88722839111672999628.\n ///\n /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function exp(int256 x) internal pure returns (int256 result) {\n // Without this check, the value passed to \"exp2\" would be less than -59794705707972522261.\n if (x < -41446531673892822322) {\n return 0;\n }\n\n // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n require(x < 88722839111672999628);\n\n // Do the fixed-point multiplication inline to save gas.\n unchecked {\n int256 doubleScaleProduct = x * LOG2_E;\n result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n }\n }\n\n /// @notice Calculates the binary exponent of x using the binary fraction method.\n ///\n /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n ///\n /// Requirements:\n /// - x must be 128e18 or less.\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - For any x less than -59794705707972522261, the result is zero.\n ///\n /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function exp2(int256 x) internal pure returns (int256 result) {\n // This works because 2^(-x) = 1/2^x.\n if (x < 0) {\n // 2**59.794705707972522262 is the maximum number whose inverse does not turn into zero.\n if (x < -59794705707972522261) {\n return 0;\n }\n\n // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n unchecked { result = 1e36 / exp2(-x); }\n } else {\n // 2**128 doesn't fit within the 128.128-bit fixed-point representation.\n require(x < 128e18);\n\n unchecked {\n // Convert x to the 128.128-bit fixed-point format.\n uint256 x128x128 = (uint256(x) << 128) / uint256(SCALE);\n\n // Safe to convert the result to int256 directly because the maximum input allowed is 128e18.\n result = int256(PRBMathCommon.exp2(x128x128));\n }\n }\n }\n\n /// @notice Yields the greatest signed 59.18 decimal fixed-point number less than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be greater than or equal to MIN_WHOLE_SD59x18.\n ///\n /// @param x The signed 59.18-decimal fixed-point number to floor.\n /// @param result The greatest integer less than or equal to x, as a signed 58.18-decimal fixed-point number.\n function floor(int256 x) internal pure returns (int256 result) {\n require(x >= MIN_WHOLE_SD59x18);\n unchecked {\n int256 remainder = x % SCALE;\n if (remainder == 0) {\n result = x;\n } else {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n result = x - remainder;\n if (x < 0) {\n result -= SCALE;\n }\n }\n }\n }\n\n /// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right\n /// of the radix point for negative numbers.\n /// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n /// @param x The signed 59.18-decimal fixed-point number to get the fractional part of.\n /// @param result The fractional part of x as a signed 59.18-decimal fixed-point number.\n function frac(int256 x) internal pure returns (int256 result) {\n unchecked { result = x % SCALE; }\n }\n\n /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n ///\n /// @dev Requirements:\n /// - x * y must fit within MAX_SD59x18, lest it overflows.\n /// - x * y cannot be negative.\n ///\n /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function gm(int256 x, int256 y) internal pure returns (int256 result) {\n if (x == 0) {\n return 0;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n int256 xy = x * y;\n require(xy / x == y);\n\n // The product cannot be negative.\n require(xy >= 0);\n\n // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n // during multiplication. See the comments within the \"sqrt\" function.\n result = int256(PRBMathCommon.sqrt(uint256(xy)));\n }\n }\n\n /// @notice Calculates 1 / x, rounding towards zero.\n ///\n /// @dev Requirements:\n /// - x cannot be zero.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the inverse.\n /// @return result The inverse as a signed 59.18-decimal fixed-point number.\n function inv(int256 x) internal pure returns (int256 result) {\n unchecked {\n // 1e36 is SCALE * SCALE.\n result = 1e36 / x;\n }\n }\n\n /// @notice Calculates the natural logarithm of x.\n ///\n /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the natural logarithm.\n /// @return result The natural logarithm as a signed 59.18-decimal fixed-point number.\n function ln(int256 x) internal pure returns (int256 result) {\n // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n // can return is 195205294292027477728.\n unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n }\n\n /// @notice Calculates the common logarithm of x.\n ///\n /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the common logarithm.\n /// @return result The common logarithm as a signed 59.18-decimal fixed-point number.\n function log10(int256 x) internal pure returns (int256 result) {\n require(x > 0);\n\n // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n // prettier-ignore\n assembly {\n switch x\n case 1 { result := mul(SCALE, sub(0, 18)) }\n case 10 { result := mul(SCALE, sub(1, 18)) }\n case 100 { result := mul(SCALE, sub(2, 18)) }\n case 1000 { result := mul(SCALE, sub(3, 18)) }\n case 10000 { result := mul(SCALE, sub(4, 18)) }\n case 100000 { result := mul(SCALE, sub(5, 18)) }\n case 1000000 { result := mul(SCALE, sub(6, 18)) }\n case 10000000 { result := mul(SCALE, sub(7, 18)) }\n case 100000000 { result := mul(SCALE, sub(8, 18)) }\n case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := SCALE }\n case 100000000000000000000 { result := mul(SCALE, 2) }\n case 1000000000000000000000 { result := mul(SCALE, 3) }\n case 10000000000000000000000 { result := mul(SCALE, 4) }\n case 100000000000000000000000 { result := mul(SCALE, 5) }\n case 1000000000000000000000000 { result := mul(SCALE, 6) }\n case 10000000000000000000000000 { result := mul(SCALE, 7) }\n case 100000000000000000000000000 { result := mul(SCALE, 8) }\n case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n default {\n result := MAX_SD59x18\n }\n }\n\n if (result == MAX_SD59x18) {\n // Do the fixed-point division inline to save gas. The denominator is log2(10).\n unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n }\n }\n\n /// @notice Calculates the binary logarithm of x.\n ///\n /// @dev Based on the iterative approximation algorithm.\n /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n ///\n /// Requirements:\n /// - x must be greater than zero.\n ///\n /// Caveats:\n /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm.\n /// @return result The binary logarithm as a signed 59.18-decimal fixed-point number.\n function log2(int256 x) internal pure returns (int256 result) {\n require(x > 0);\n unchecked {\n // This works because log2(x) = -log2(1/x).\n int256 sign;\n if (x >= SCALE) {\n sign = 1;\n } else {\n sign = -1;\n // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n assembly {\n x := div(1000000000000000000000000000000000000, x)\n }\n }\n\n // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n uint256 n = PRBMathCommon.mostSignificantBit(uint256(x / SCALE));\n\n // The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow\n // because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1.\n result = int256(n) * SCALE;\n\n // This is y = x * 2^(-n).\n int256 y = x >> n;\n\n // If y = 1, the fractional part is zero.\n if (y == SCALE) {\n return result * sign;\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n for (int256 delta = int256(HALF_SCALE); delta > 0; delta >>= 1) {\n y = (y * y) / SCALE;\n\n // Is y^2 > 2 and so in the range [2,4)?\n if (y >= 2 * SCALE) {\n // Add the 2^(-m) factor to the logarithm.\n result += delta;\n\n // Corresponds to z/2 on Wikipedia.\n y >>= 1;\n }\n }\n result *= sign;\n }\n }\n\n /// @notice Multiplies two signed 59.18-decimal fixed-point numbers together, returning a new signed 59.18-decimal\n /// fixed-point number.\n ///\n /// @dev Variant of \"mulDiv\" that works with signed numbers and employs constant folding, i.e. the denominator is\n /// alawys 1e18.\n ///\n /// Requirements:\n /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - The body is purposely left uncommented; see the NatSpec comments in \"PRBMathCommon.mulDiv\" to understand how this works.\n ///\n /// @param x The multiplicand as a signed 59.18-decimal fixed-point number.\n /// @param y The multiplier as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function mul(int256 x, int256 y) internal pure returns (int256 result) {\n require(x > MIN_SD59x18);\n require(y > MIN_SD59x18);\n\n unchecked {\n uint256 ax;\n uint256 ay;\n ax = x < 0 ? uint256(-x) : uint256(x);\n ay = y < 0 ? uint256(-y) : uint256(y);\n\n uint256 resultUnsigned = PRBMathCommon.mulDivFixedPoint(ax, ay);\n require(resultUnsigned <= uint256(MAX_SD59x18));\n\n uint256 sx;\n uint256 sy;\n assembly {\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n }\n result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n }\n }\n\n /// @notice Retrieves PI as a signed 59.18-decimal fixed-point number.\n function pi() internal pure returns (int256 result) {\n result = 3141592653589793238;\n }\n\n /// @notice Raises x (signed 59.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n /// famous algorithm \"exponentiation by squaring\".\n ///\n /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n ///\n /// Requirements:\n /// - All from \"abs\" and \"PRBMathCommon.mulDivFixedPoint\".\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n /// - Assumes 0^0 is 1.\n ///\n /// @param x The base as a signed 59.18-decimal fixed-point number.\n /// @param y The exponent as an uint256.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function pow(int256 x, uint256 y) internal pure returns (int256 result) {\n uint256 absX = uint256(abs(x));\n\n // Calculate the first iteration of the loop in advance.\n uint256 absResult = y & 1 > 0 ? absX : uint256(SCALE);\n\n // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n for (y >>= 1; y > 0; y >>= 1) {\n absX = PRBMathCommon.mulDivFixedPoint(absX, absX);\n\n // Equivalent to \"y % 2 == 1\" but faster.\n if (y & 1 > 0) {\n absResult = PRBMathCommon.mulDivFixedPoint(absResult, absX);\n }\n }\n\n // The result must fit within the 59.18-decimal fixed-point representation.\n require(absResult <= uint256(MAX_SD59x18));\n\n // Is the base negative and the exponent an odd number?\n bool isNegative = x < 0 && y & 1 == 1;\n result = isNegative ? -int256(absResult) : int256(absResult);\n }\n\n /// @notice Returns 1 as a signed 59.18-decimal fixed-point number.\n function scale() internal pure returns (int256 result) {\n result = SCALE;\n }\n\n /// @notice Calculates the square root of x, rounding down.\n /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n ///\n /// Requirements:\n /// - x cannot be negative.\n /// - x must be less than MAX_SD59x18 / SCALE.\n ///\n /// Caveats:\n /// - The maximum fixed-point number permitted is 57896044618658097711785492504343953926634.992332820282019729.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the square root.\n /// @return result The result as a signed 59.18-decimal fixed-point .\n function sqrt(int256 x) internal pure returns (int256 result) {\n require(x >= 0);\n require(x < 57896044618658097711785492504343953926634992332820282019729);\n unchecked {\n // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two signed\n // 59.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n result = int256(PRBMathCommon.sqrt(uint256(x * SCALE)));\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18.sol b/examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18.sol new file mode 100644 index 00000000..0313481f --- /dev/null +++ b/examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18.sol @@ -0,0 +1,437 @@ +// SPDX-License-Identifier: WTFPL +pragma solidity >=0.8.0; + +import "./PRBMathCommon.sol"; + +/// @title PRBMathUD60x18 +/// @author Paul Razvan Berg +/// @notice Smart contract library for advanced fixed-point math. It works with uint256 numbers considered to have 18 +/// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60 +/// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the +/// maximum values permitted by the Solidity type uint256. +library PRBMathUD60x18 { + /// @dev Half the SCALE number. + uint256 internal constant HALF_SCALE = 5e17; + + /// @dev log2(e) as an unsigned 60.18-decimal fixed-point number. + uint256 internal constant LOG2_E = 1442695040888963407; + + /// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have. + uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + /// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have. + uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000; + + /// @dev How many trailing decimals can be represented. + uint256 internal constant SCALE = 1e18; + + /// @notice Calculates arithmetic average of x and y, rounding down. + /// @param x The first operand as an unsigned 60.18-decimal fixed-point number. + /// @param y The second operand as an unsigned 60.18-decimal fixed-point number. + /// @return result The arithmetic average as an unsigned 60.18-decimal fixed-point number. + function avg(uint256 x, uint256 y) internal pure returns (uint256 result) { + // The operations can never overflow. + unchecked { + // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need + // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice. + result = (x >> 1) + (y >> 1) + (x & y & 1); + } + } + + /// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x. + /// + /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts. + /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions. + /// + /// Requirements: + /// - x must be less than or equal to MAX_WHOLE_UD60x18. + /// + /// @param x The unsigned 60.18-decimal fixed-point number to ceil. + /// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number. + function ceil(uint256 x) internal pure returns (uint256 result) { + require(x <= MAX_WHOLE_UD60x18); + assembly { + // Equivalent to "x % SCALE" but faster. + let remainder := mod(x, SCALE) + + // Equivalent to "SCALE - remainder" but faster. + let delta := sub(SCALE, remainder) + + // Equivalent to "x + delta * (remainder > 0 ? 1 : 0)" but faster. + result := add(x, mul(delta, gt(remainder, 0))) + } + } + + /// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number. + /// + /// @dev Uses mulDiv to enable overflow-safe multiplication and division. + /// + /// Requirements: + /// - y cannot be zero. + /// + /// @param x The numerator as an unsigned 60.18-decimal fixed-point number. + /// @param y The denominator as an unsigned 60.18-decimal fixed-point number. + /// @param result The quotient as an unsigned 60.18-decimal fixed-point number. + function div(uint256 x, uint256 y) internal pure returns (uint256 result) { + result = PRBMathCommon.mulDiv(x, SCALE, y); + } + + /// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number. + /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant). + function e() internal pure returns (uint256 result) { + result = 2718281828459045235; + } + + /// @notice Calculates the natural exponent of x. + /// + /// @dev Based on the insight that e^x = 2^(x * log2(e)). + /// + /// Requirements: + /// - All from "log2". + /// - x must be less than 88722839111672999628. + /// + /// @param x The exponent as an unsigned 60.18-decimal fixed-point number. + /// @return result The result as an unsigned 60.18-decimal fixed-point number. + function exp(uint256 x) internal pure returns (uint256 result) { + // Without this check, the value passed to "exp2" would be greater than 128e18. + require(x < 88722839111672999628); + + // Do the fixed-point multiplication inline to save gas. + unchecked { + uint256 doubleScaleProduct = x * LOG2_E; + result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE); + } + } + + /// @notice Calculates the binary exponent of x using the binary fraction method. + /// + /// @dev See https://ethereum.stackexchange.com/q/79903/24693. + /// + /// Requirements: + /// - x must be 128e18 or less. + /// - The result must fit within MAX_UD60x18. + /// + /// @param x The exponent as an unsigned 60.18-decimal fixed-point number. + /// @return result The result as an unsigned 60.18-decimal fixed-point number. + function exp2(uint256 x) internal pure returns (uint256 result) { + // 2**128 doesn't fit within the 128.128-bit format used internally in this function. + require(x < 128e18); + + unchecked { + // Convert x to the 128.128-bit fixed-point format. + uint256 x128x128 = (x << 128) / SCALE; + + // Pass x to the PRBMathCommon.exp2 function, which uses the 128.128-bit fixed-point number representation. + result = PRBMathCommon.exp2(x128x128); + } + } + + /// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x. + /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts. + /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions. + /// @param x The unsigned 60.18-decimal fixed-point number to floor. + /// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number. + function floor(uint256 x) internal pure returns (uint256 result) { + assembly { + // Equivalent to "x % SCALE" but faster. + let remainder := mod(x, SCALE) + + // Equivalent to "x - remainder * (remainder > 0 ? 1 : 0)" but faster. + result := sub(x, mul(remainder, gt(remainder, 0))) + } + } + + /// @notice Yields the excess beyond the floor of x. + /// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part. + /// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of. + /// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number. + function frac(uint256 x) internal pure returns (uint256 result) { + assembly { + result := mod(x, SCALE) + } + } + + /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down. + /// + /// @dev Requirements: + /// - x * y must fit within MAX_UD60x18, lest it overflows. + /// + /// @param x The first operand as an unsigned 60.18-decimal fixed-point number. + /// @param y The second operand as an unsigned 60.18-decimal fixed-point number. + /// @return result The result as an unsigned 60.18-decimal fixed-point number. + function gm(uint256 x, uint256 y) internal pure returns (uint256 result) { + if (x == 0) { + return 0; + } + + unchecked { + // Checking for overflow this way is faster than letting Solidity do it. + uint256 xy = x * y; + require(xy / x == y); + + // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE + // during multiplication. See the comments within the "sqrt" function. + result = PRBMathCommon.sqrt(xy); + } + } + + /// @notice Calculates 1 / x, rounding towards zero. + /// + /// @dev Requirements: + /// - x cannot be zero. + /// + /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse. + /// @return result The inverse as an unsigned 60.18-decimal fixed-point number. + function inv(uint256 x) internal pure returns (uint256 result) { + unchecked { + // 1e36 is SCALE * SCALE. + result = 1e36 / x; + } + } + + /// @notice Calculates the natural logarithm of x. + /// + /// @dev Based on the insight that ln(x) = log2(x) / log2(e). + /// + /// Requirements: + /// - All from "log2". + /// + /// Caveats: + /// - All from "log2". + /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision. + /// + /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm. + /// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number. + function ln(uint256 x) internal pure returns (uint256 result) { + // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x) + // can return is 196205294292027477728. + unchecked { result = (log2(x) * SCALE) / LOG2_E; } + } + + /// @notice Calculates the common logarithm of x. + /// + /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common + /// logarithm based on the insight that log10(x) = log2(x) / log2(10). + /// + /// Requirements: + /// - All from "log2". + /// + /// Caveats: + /// - All from "log2". + /// + /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm. + /// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number. + function log10(uint256 x) internal pure returns (uint256 result) { + require(x >= SCALE); + + // Note that the "mul" in this block is the assembly mul operation, not the "mul" function defined in this contract. + // prettier-ignore + assembly { + switch x + case 1 { result := mul(SCALE, sub(0, 18)) } + case 10 { result := mul(SCALE, sub(1, 18)) } + case 100 { result := mul(SCALE, sub(2, 18)) } + case 1000 { result := mul(SCALE, sub(3, 18)) } + case 10000 { result := mul(SCALE, sub(4, 18)) } + case 100000 { result := mul(SCALE, sub(5, 18)) } + case 1000000 { result := mul(SCALE, sub(6, 18)) } + case 10000000 { result := mul(SCALE, sub(7, 18)) } + case 100000000 { result := mul(SCALE, sub(8, 18)) } + case 1000000000 { result := mul(SCALE, sub(9, 18)) } + case 10000000000 { result := mul(SCALE, sub(10, 18)) } + case 100000000000 { result := mul(SCALE, sub(11, 18)) } + case 1000000000000 { result := mul(SCALE, sub(12, 18)) } + case 10000000000000 { result := mul(SCALE, sub(13, 18)) } + case 100000000000000 { result := mul(SCALE, sub(14, 18)) } + case 1000000000000000 { result := mul(SCALE, sub(15, 18)) } + case 10000000000000000 { result := mul(SCALE, sub(16, 18)) } + case 100000000000000000 { result := mul(SCALE, sub(17, 18)) } + case 1000000000000000000 { result := 0 } + case 10000000000000000000 { result := SCALE } + case 100000000000000000000 { result := mul(SCALE, 2) } + case 1000000000000000000000 { result := mul(SCALE, 3) } + case 10000000000000000000000 { result := mul(SCALE, 4) } + case 100000000000000000000000 { result := mul(SCALE, 5) } + case 1000000000000000000000000 { result := mul(SCALE, 6) } + case 10000000000000000000000000 { result := mul(SCALE, 7) } + case 100000000000000000000000000 { result := mul(SCALE, 8) } + case 1000000000000000000000000000 { result := mul(SCALE, 9) } + case 10000000000000000000000000000 { result := mul(SCALE, 10) } + case 100000000000000000000000000000 { result := mul(SCALE, 11) } + case 1000000000000000000000000000000 { result := mul(SCALE, 12) } + case 10000000000000000000000000000000 { result := mul(SCALE, 13) } + case 100000000000000000000000000000000 { result := mul(SCALE, 14) } + case 1000000000000000000000000000000000 { result := mul(SCALE, 15) } + case 10000000000000000000000000000000000 { result := mul(SCALE, 16) } + case 100000000000000000000000000000000000 { result := mul(SCALE, 17) } + case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) } + case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) } + case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) } + case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) } + case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) } + case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) } + case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) } + case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) } + case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) } + case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) } + case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) } + case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) } + case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) } + case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) } + case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) } + case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) } + case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) } + case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) } + case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) } + case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) } + case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) } + case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) } + case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) } + case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) } + case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) } + case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) } + case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) } + case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) } + case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) } + case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) } + case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) } + case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) } + case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) } + case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) } + case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) } + case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) } + case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) } + case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) } + case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) } + case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) } + case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) } + case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) } + default { + result := MAX_UD60x18 + } + } + + if (result == MAX_UD60x18) { + // Do the fixed-point division inline to save gas. The denominator is log2(10). + unchecked { result = (log2(x) * SCALE) / 332192809488736234; } + } + } + + /// @notice Calculates the binary logarithm of x. + /// + /// @dev Based on the iterative approximation algorithm. + /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation + /// + /// Requirements: + /// - x must be greater than or equal to SCALE, otherwise the result would be negative. + /// + /// Caveats: + /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation. + /// + /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm. + /// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number. + function log2(uint256 x) internal pure returns (uint256 result) { + require(x >= SCALE); + unchecked { + // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n). + uint256 n = PRBMathCommon.mostSignificantBit(x / SCALE); + + // The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow + // because n is maximum 255 and SCALE is 1e18. + result = n * SCALE; + + // This is y = x * 2^(-n). + uint256 y = x >> n; + + // If y = 1, the fractional part is zero. + if (y == SCALE) { + return result; + } + + // Calculate the fractional part via the iterative approximation. + // The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster. + for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) { + y = (y * y) / SCALE; + + // Is y^2 > 2 and so in the range [2,4)? + if (y >= 2 * SCALE) { + // Add the 2^(-m) factor to the logarithm. + result += delta; + + // Corresponds to z/2 on Wikipedia. + y >>= 1; + } + } + } + } + + /// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal + /// fixed-point number. + /// @dev See the documentation for the "PRBMathCommon.mulDivFixedPoint" function. + /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number. + /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number. + /// @return result The result as an unsigned 60.18-decimal fixed-point number. + function mul(uint256 x, uint256 y) internal pure returns (uint256 result) { + result = PRBMathCommon.mulDivFixedPoint(x, y); + } + + /// @notice Retrieves PI as an unsigned 60.18-decimal fixed-point number. + function pi() internal pure returns (uint256 result) { + result = 3141592653589793238; + } + + /// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the + /// famous algorithm "exponentiation by squaring". + /// + /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring + /// + /// Requirements: + /// - The result must fit within MAX_UD60x18. + /// + /// Caveats: + /// - All from "mul". + /// - Assumes 0^0 is 1. + /// + /// @param x The base as an unsigned 60.18-decimal fixed-point number. + /// @param y The exponent as an uint256. + /// @return result The result as an unsigned 60.18-decimal fixed-point number. + function pow(uint256 x, uint256 y) internal pure returns (uint256 result) { + // Calculate the first iteration of the loop in advance. + result = y & 1 > 0 ? x : SCALE; + + // Equivalent to "for(y /= 2; y > 0; y /= 2)" but faster. + for (y >>= 1; y > 0; y >>= 1) { + x = PRBMathCommon.mulDivFixedPoint(x, x); + + // Equivalent to "y % 2 == 1" but faster. + if (y & 1 > 0) { + result = PRBMathCommon.mulDivFixedPoint(result, x); + } + } + } + + /// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number. + function scale() internal pure returns (uint256 result) { + result = SCALE; + } + + /// @notice Calculates the square root of x, rounding down. + /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method. + /// + /// Requirements: + /// - x must be less than MAX_UD60x18 / SCALE. + /// + /// Caveats: + /// - The maximum fixed-point number permitted is 115792089237316195423570985008687907853269.984665640564039458. + /// + /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root. + /// @return result The result as an unsigned 60.18-decimal fixed-point . + function sqrt(uint256 x) internal pure returns (uint256 result) { + require(x < 115792089237316195423570985008687907853269984665640564039458); + unchecked { + // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned + // 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root). + result = PRBMathCommon.sqrt(x * SCALE); + } + } +} diff --git a/examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18_standard_input.json b/examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18_standard_input.json new file mode 100644 index 00000000..ae4085fc --- /dev/null +++ b/examples/test/semanticTests/externalContracts__prbmath_PRBMathUD60x18/PRBMathUD60x18_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "PRBMathSD59x18.sol": { + "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathSD59x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with int256 numbers considered to have 18\n/// trailing decimals. We call this number representation signed 59.18-decimal fixed-point, since the numbers can have\n/// a sign and there can be up to 59 digits in the integer part and up to 18 decimals in the fractional part. The numbers\n/// are bound by the minimum and the maximum values permitted by the Solidity type int256.\nlibrary PRBMathSD59x18 {\n /// @dev log2(e) as a signed 59.18-decimal fixed-point number.\n int256 internal constant LOG2_E = 1442695040888963407;\n\n /// @dev Half the SCALE number.\n int256 internal constant HALF_SCALE = 5e17;\n\n /// @dev The maximum value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728792003956564819967;\n\n /// @dev The maximum whole value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n /// @dev The minimum value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n /// @dev The minimum whole value a signed 59.18-decimal fixed-point number can have.\n int256 internal constant MIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728000000000000000000;\n\n /// @dev How many trailing decimals can be represented.\n int256 internal constant SCALE = 1e18;\n\n /// INTERNAL FUNCTIONS ///\n\n /// @notice Calculate the absolute value of x.\n ///\n /// @dev Requirements:\n /// - x must be greater than MIN_SD59x18.\n ///\n /// @param x The number to calculate the absolute value for.\n /// @param result The absolute value of x.\n function abs(int256 x) internal pure returns (int256 result) {\n unchecked {\n require(x > MIN_SD59x18);\n result = x < 0 ? -x : x;\n }\n }\n\n /// @notice Calculates arithmetic average of x and y, rounding down.\n /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n /// @return result The arithmetic average as a signed 59.18-decimal fixed-point number.\n function avg(int256 x, int256 y) internal pure returns (int256 result) {\n // The operations can never overflow.\n unchecked {\n // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n result = (x >> 1) + (y >> 1) + (x & y & 1);\n }\n }\n\n /// @notice Yields the least greatest signed 59.18 decimal fixed-point number greater than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be less than or equal to MAX_WHOLE_SD59x18.\n ///\n /// @param x The signed 59.18-decimal fixed-point number to ceil.\n /// @param result The least integer greater than or equal to x, as a signed 58.18-decimal fixed-point number.\n function ceil(int256 x) internal pure returns (int256 result) {\n require(x <= MAX_WHOLE_SD59x18);\n unchecked {\n int256 remainder = x % SCALE;\n if (remainder == 0) {\n result = x;\n } else {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n result = x - remainder;\n if (x > 0) {\n result += SCALE;\n }\n }\n }\n }\n\n /// @notice Divides two signed 59.18-decimal fixed-point numbers, returning a new signed 59.18-decimal fixed-point number.\n ///\n /// @dev Variant of \"mulDiv\" that works with signed numbers. Works by computing the signs and the absolute values separately.\n ///\n /// Requirements:\n /// - All from \"PRBMathCommon.mulDiv\".\n /// - None of the inputs can be type(int256).min.\n /// - y cannot be zero.\n /// - The result must fit within int256.\n ///\n /// Caveats:\n /// - All from \"PRBMathCommon.mulDiv\".\n ///\n /// @param x The numerator as a signed 59.18-decimal fixed-point number.\n /// @param y The denominator as a signed 59.18-decimal fixed-point number.\n /// @param result The quotient as a signed 59.18-decimal fixed-point number.\n function div(int256 x, int256 y) internal pure returns (int256 result) {\n require(x > type(int256).min);\n require(y > type(int256).min);\n\n // Get hold of the absolute values of x and y.\n uint256 ax;\n uint256 ay;\n unchecked {\n ax = x < 0 ? uint256(-x) : uint256(x);\n ay = y < 0 ? uint256(-y) : uint256(y);\n }\n\n // Compute the absolute value of (x*SCALE)\u00f7y. The result must fit within int256.\n uint256 resultUnsigned = PRBMathCommon.mulDiv(ax, uint256(SCALE), ay);\n require(resultUnsigned <= uint256(type(int256).max));\n\n // Get the signs of x and y.\n uint256 sx;\n uint256 sy;\n assembly {\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n }\n\n // XOR over sx and sy. This is basically checking whether the inputs have the same sign. If yes, the result\n // should be positive. Otherwise, it should be negative.\n result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n }\n\n /// @notice Returns Euler's number as a signed 59.18-decimal fixed-point number.\n /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n function e() internal pure returns (int256 result) {\n result = 2718281828459045235;\n }\n\n /// @notice Calculates the natural exponent of x.\n ///\n /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n ///\n /// Requirements:\n /// - All from \"log2\".\n /// - x must be less than 88722839111672999628.\n ///\n /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function exp(int256 x) internal pure returns (int256 result) {\n // Without this check, the value passed to \"exp2\" would be less than -59794705707972522261.\n if (x < -41446531673892822322) {\n return 0;\n }\n\n // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n require(x < 88722839111672999628);\n\n // Do the fixed-point multiplication inline to save gas.\n unchecked {\n int256 doubleScaleProduct = x * LOG2_E;\n result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n }\n }\n\n /// @notice Calculates the binary exponent of x using the binary fraction method.\n ///\n /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n ///\n /// Requirements:\n /// - x must be 128e18 or less.\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - For any x less than -59794705707972522261, the result is zero.\n ///\n /// @param x The exponent as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function exp2(int256 x) internal pure returns (int256 result) {\n // This works because 2^(-x) = 1/2^x.\n if (x < 0) {\n // 2**59.794705707972522262 is the maximum number whose inverse does not turn into zero.\n if (x < -59794705707972522261) {\n return 0;\n }\n\n // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n unchecked { result = 1e36 / exp2(-x); }\n } else {\n // 2**128 doesn't fit within the 128.128-bit fixed-point representation.\n require(x < 128e18);\n\n unchecked {\n // Convert x to the 128.128-bit fixed-point format.\n uint256 x128x128 = (uint256(x) << 128) / uint256(SCALE);\n\n // Safe to convert the result to int256 directly because the maximum input allowed is 128e18.\n result = int256(PRBMathCommon.exp2(x128x128));\n }\n }\n }\n\n /// @notice Yields the greatest signed 59.18 decimal fixed-point number less than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be greater than or equal to MIN_WHOLE_SD59x18.\n ///\n /// @param x The signed 59.18-decimal fixed-point number to floor.\n /// @param result The greatest integer less than or equal to x, as a signed 58.18-decimal fixed-point number.\n function floor(int256 x) internal pure returns (int256 result) {\n require(x >= MIN_WHOLE_SD59x18);\n unchecked {\n int256 remainder = x % SCALE;\n if (remainder == 0) {\n result = x;\n } else {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n result = x - remainder;\n if (x < 0) {\n result -= SCALE;\n }\n }\n }\n }\n\n /// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right\n /// of the radix point for negative numbers.\n /// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n /// @param x The signed 59.18-decimal fixed-point number to get the fractional part of.\n /// @param result The fractional part of x as a signed 59.18-decimal fixed-point number.\n function frac(int256 x) internal pure returns (int256 result) {\n unchecked { result = x % SCALE; }\n }\n\n /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n ///\n /// @dev Requirements:\n /// - x * y must fit within MAX_SD59x18, lest it overflows.\n /// - x * y cannot be negative.\n ///\n /// @param x The first operand as a signed 59.18-decimal fixed-point number.\n /// @param y The second operand as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function gm(int256 x, int256 y) internal pure returns (int256 result) {\n if (x == 0) {\n return 0;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n int256 xy = x * y;\n require(xy / x == y);\n\n // The product cannot be negative.\n require(xy >= 0);\n\n // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n // during multiplication. See the comments within the \"sqrt\" function.\n result = int256(PRBMathCommon.sqrt(uint256(xy)));\n }\n }\n\n /// @notice Calculates 1 / x, rounding towards zero.\n ///\n /// @dev Requirements:\n /// - x cannot be zero.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the inverse.\n /// @return result The inverse as a signed 59.18-decimal fixed-point number.\n function inv(int256 x) internal pure returns (int256 result) {\n unchecked {\n // 1e36 is SCALE * SCALE.\n result = 1e36 / x;\n }\n }\n\n /// @notice Calculates the natural logarithm of x.\n ///\n /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the natural logarithm.\n /// @return result The natural logarithm as a signed 59.18-decimal fixed-point number.\n function ln(int256 x) internal pure returns (int256 result) {\n // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n // can return is 195205294292027477728.\n unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n }\n\n /// @notice Calculates the common logarithm of x.\n ///\n /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the common logarithm.\n /// @return result The common logarithm as a signed 59.18-decimal fixed-point number.\n function log10(int256 x) internal pure returns (int256 result) {\n require(x > 0);\n\n // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n // prettier-ignore\n assembly {\n switch x\n case 1 { result := mul(SCALE, sub(0, 18)) }\n case 10 { result := mul(SCALE, sub(1, 18)) }\n case 100 { result := mul(SCALE, sub(2, 18)) }\n case 1000 { result := mul(SCALE, sub(3, 18)) }\n case 10000 { result := mul(SCALE, sub(4, 18)) }\n case 100000 { result := mul(SCALE, sub(5, 18)) }\n case 1000000 { result := mul(SCALE, sub(6, 18)) }\n case 10000000 { result := mul(SCALE, sub(7, 18)) }\n case 100000000 { result := mul(SCALE, sub(8, 18)) }\n case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := SCALE }\n case 100000000000000000000 { result := mul(SCALE, 2) }\n case 1000000000000000000000 { result := mul(SCALE, 3) }\n case 10000000000000000000000 { result := mul(SCALE, 4) }\n case 100000000000000000000000 { result := mul(SCALE, 5) }\n case 1000000000000000000000000 { result := mul(SCALE, 6) }\n case 10000000000000000000000000 { result := mul(SCALE, 7) }\n case 100000000000000000000000000 { result := mul(SCALE, 8) }\n case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n default {\n result := MAX_SD59x18\n }\n }\n\n if (result == MAX_SD59x18) {\n // Do the fixed-point division inline to save gas. The denominator is log2(10).\n unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n }\n }\n\n /// @notice Calculates the binary logarithm of x.\n ///\n /// @dev Based on the iterative approximation algorithm.\n /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n ///\n /// Requirements:\n /// - x must be greater than zero.\n ///\n /// Caveats:\n /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the binary logarithm.\n /// @return result The binary logarithm as a signed 59.18-decimal fixed-point number.\n function log2(int256 x) internal pure returns (int256 result) {\n require(x > 0);\n unchecked {\n // This works because log2(x) = -log2(1/x).\n int256 sign;\n if (x >= SCALE) {\n sign = 1;\n } else {\n sign = -1;\n // Do the fixed-point inversion inline to save gas. The numerator is SCALE * SCALE.\n assembly {\n x := div(1000000000000000000000000000000000000, x)\n }\n }\n\n // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n uint256 n = PRBMathCommon.mostSignificantBit(uint256(x / SCALE));\n\n // The integer part of the logarithm as a signed 59.18-decimal fixed-point number. The operation can't overflow\n // because n is maximum 255, SCALE is 1e18 and sign is either 1 or -1.\n result = int256(n) * SCALE;\n\n // This is y = x * 2^(-n).\n int256 y = x >> n;\n\n // If y = 1, the fractional part is zero.\n if (y == SCALE) {\n return result * sign;\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n for (int256 delta = int256(HALF_SCALE); delta > 0; delta >>= 1) {\n y = (y * y) / SCALE;\n\n // Is y^2 > 2 and so in the range [2,4)?\n if (y >= 2 * SCALE) {\n // Add the 2^(-m) factor to the logarithm.\n result += delta;\n\n // Corresponds to z/2 on Wikipedia.\n y >>= 1;\n }\n }\n result *= sign;\n }\n }\n\n /// @notice Multiplies two signed 59.18-decimal fixed-point numbers together, returning a new signed 59.18-decimal\n /// fixed-point number.\n ///\n /// @dev Variant of \"mulDiv\" that works with signed numbers and employs constant folding, i.e. the denominator is\n /// alawys 1e18.\n ///\n /// Requirements:\n /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - The body is purposely left uncommented; see the NatSpec comments in \"PRBMathCommon.mulDiv\" to understand how this works.\n ///\n /// @param x The multiplicand as a signed 59.18-decimal fixed-point number.\n /// @param y The multiplier as a signed 59.18-decimal fixed-point number.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function mul(int256 x, int256 y) internal pure returns (int256 result) {\n require(x > MIN_SD59x18);\n require(y > MIN_SD59x18);\n\n unchecked {\n uint256 ax;\n uint256 ay;\n ax = x < 0 ? uint256(-x) : uint256(x);\n ay = y < 0 ? uint256(-y) : uint256(y);\n\n uint256 resultUnsigned = PRBMathCommon.mulDivFixedPoint(ax, ay);\n require(resultUnsigned <= uint256(MAX_SD59x18));\n\n uint256 sx;\n uint256 sy;\n assembly {\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n }\n result = sx ^ sy == 1 ? -int256(resultUnsigned) : int256(resultUnsigned);\n }\n }\n\n /// @notice Retrieves PI as a signed 59.18-decimal fixed-point number.\n function pi() internal pure returns (int256 result) {\n result = 3141592653589793238;\n }\n\n /// @notice Raises x (signed 59.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n /// famous algorithm \"exponentiation by squaring\".\n ///\n /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n ///\n /// Requirements:\n /// - All from \"abs\" and \"PRBMathCommon.mulDivFixedPoint\".\n /// - The result must fit within MAX_SD59x18.\n ///\n /// Caveats:\n /// - All from \"PRBMathCommon.mulDivFixedPoint\".\n /// - Assumes 0^0 is 1.\n ///\n /// @param x The base as a signed 59.18-decimal fixed-point number.\n /// @param y The exponent as an uint256.\n /// @return result The result as a signed 59.18-decimal fixed-point number.\n function pow(int256 x, uint256 y) internal pure returns (int256 result) {\n uint256 absX = uint256(abs(x));\n\n // Calculate the first iteration of the loop in advance.\n uint256 absResult = y & 1 > 0 ? absX : uint256(SCALE);\n\n // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n for (y >>= 1; y > 0; y >>= 1) {\n absX = PRBMathCommon.mulDivFixedPoint(absX, absX);\n\n // Equivalent to \"y % 2 == 1\" but faster.\n if (y & 1 > 0) {\n absResult = PRBMathCommon.mulDivFixedPoint(absResult, absX);\n }\n }\n\n // The result must fit within the 59.18-decimal fixed-point representation.\n require(absResult <= uint256(MAX_SD59x18));\n\n // Is the base negative and the exponent an odd number?\n bool isNegative = x < 0 && y & 1 == 1;\n result = isNegative ? -int256(absResult) : int256(absResult);\n }\n\n /// @notice Returns 1 as a signed 59.18-decimal fixed-point number.\n function scale() internal pure returns (int256 result) {\n result = SCALE;\n }\n\n /// @notice Calculates the square root of x, rounding down.\n /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n ///\n /// Requirements:\n /// - x cannot be negative.\n /// - x must be less than MAX_SD59x18 / SCALE.\n ///\n /// Caveats:\n /// - The maximum fixed-point number permitted is 57896044618658097711785492504343953926634.992332820282019729.\n ///\n /// @param x The signed 59.18-decimal fixed-point number for which to calculate the square root.\n /// @return result The result as a signed 59.18-decimal fixed-point .\n function sqrt(int256 x) internal pure returns (int256 result) {\n require(x >= 0);\n require(x < 57896044618658097711785492504343953926634992332820282019729);\n unchecked {\n // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two signed\n // 59.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n result = int256(PRBMathCommon.sqrt(uint256(x * SCALE)));\n }\n }\n}\n" + }, + "PRBMathUD60x18.sol": { + "content": "// SPDX-License-Identifier: WTFPL\npragma solidity >=0.8.0;\n\nimport \"./PRBMathCommon.sol\";\n\n/// @title PRBMathUD60x18\n/// @author Paul Razvan Berg\n/// @notice Smart contract library for advanced fixed-point math. It works with uint256 numbers considered to have 18\n/// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60\n/// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the\n/// maximum values permitted by the Solidity type uint256.\nlibrary PRBMathUD60x18 {\n /// @dev Half the SCALE number.\n uint256 internal constant HALF_SCALE = 5e17;\n\n /// @dev log2(e) as an unsigned 60.18-decimal fixed-point number.\n uint256 internal constant LOG2_E = 1442695040888963407;\n\n /// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have.\n uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n /// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have.\n uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000;\n\n /// @dev How many trailing decimals can be represented.\n uint256 internal constant SCALE = 1e18;\n\n /// @notice Calculates arithmetic average of x and y, rounding down.\n /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.\n /// @return result The arithmetic average as an unsigned 60.18-decimal fixed-point number.\n function avg(uint256 x, uint256 y) internal pure returns (uint256 result) {\n // The operations can never overflow.\n unchecked {\n // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need\n // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.\n result = (x >> 1) + (y >> 1) + (x & y & 1);\n }\n }\n\n /// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x.\n ///\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n ///\n /// Requirements:\n /// - x must be less than or equal to MAX_WHOLE_UD60x18.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number to ceil.\n /// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number.\n function ceil(uint256 x) internal pure returns (uint256 result) {\n require(x <= MAX_WHOLE_UD60x18);\n assembly {\n // Equivalent to \"x % SCALE\" but faster.\n let remainder := mod(x, SCALE)\n\n // Equivalent to \"SCALE - remainder\" but faster.\n let delta := sub(SCALE, remainder)\n\n // Equivalent to \"x + delta * (remainder > 0 ? 1 : 0)\" but faster.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n }\n\n /// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number.\n ///\n /// @dev Uses mulDiv to enable overflow-safe multiplication and division.\n ///\n /// Requirements:\n /// - y cannot be zero.\n ///\n /// @param x The numerator as an unsigned 60.18-decimal fixed-point number.\n /// @param y The denominator as an unsigned 60.18-decimal fixed-point number.\n /// @param result The quotient as an unsigned 60.18-decimal fixed-point number.\n function div(uint256 x, uint256 y) internal pure returns (uint256 result) {\n result = PRBMathCommon.mulDiv(x, SCALE, y);\n }\n\n /// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number.\n /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).\n function e() internal pure returns (uint256 result) {\n result = 2718281828459045235;\n }\n\n /// @notice Calculates the natural exponent of x.\n ///\n /// @dev Based on the insight that e^x = 2^(x * log2(e)).\n ///\n /// Requirements:\n /// - All from \"log2\".\n /// - x must be less than 88722839111672999628.\n ///\n /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function exp(uint256 x) internal pure returns (uint256 result) {\n // Without this check, the value passed to \"exp2\" would be greater than 128e18.\n require(x < 88722839111672999628);\n\n // Do the fixed-point multiplication inline to save gas.\n unchecked {\n uint256 doubleScaleProduct = x * LOG2_E;\n result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);\n }\n }\n\n /// @notice Calculates the binary exponent of x using the binary fraction method.\n ///\n /// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n ///\n /// Requirements:\n /// - x must be 128e18 or less.\n /// - The result must fit within MAX_UD60x18.\n ///\n /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function exp2(uint256 x) internal pure returns (uint256 result) {\n // 2**128 doesn't fit within the 128.128-bit format used internally in this function.\n require(x < 128e18);\n\n unchecked {\n // Convert x to the 128.128-bit fixed-point format.\n uint256 x128x128 = (x << 128) / SCALE;\n\n // Pass x to the PRBMathCommon.exp2 function, which uses the 128.128-bit fixed-point number representation.\n result = PRBMathCommon.exp2(x128x128);\n }\n }\n\n /// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x.\n /// @dev Optimised for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.\n /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n /// @param x The unsigned 60.18-decimal fixed-point number to floor.\n /// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number.\n function floor(uint256 x) internal pure returns (uint256 result) {\n assembly {\n // Equivalent to \"x % SCALE\" but faster.\n let remainder := mod(x, SCALE)\n\n // Equivalent to \"x - remainder * (remainder > 0 ? 1 : 0)\" but faster.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n }\n\n /// @notice Yields the excess beyond the floor of x.\n /// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part.\n /// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of.\n /// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number.\n function frac(uint256 x) internal pure returns (uint256 result) {\n assembly {\n result := mod(x, SCALE)\n }\n }\n\n /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.\n ///\n /// @dev Requirements:\n /// - x * y must fit within MAX_UD60x18, lest it overflows.\n ///\n /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function gm(uint256 x, uint256 y) internal pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xy = x * y;\n require(xy / x == y);\n\n // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE\n // during multiplication. See the comments within the \"sqrt\" function.\n result = PRBMathCommon.sqrt(xy);\n }\n }\n\n /// @notice Calculates 1 / x, rounding towards zero.\n ///\n /// @dev Requirements:\n /// - x cannot be zero.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse.\n /// @return result The inverse as an unsigned 60.18-decimal fixed-point number.\n function inv(uint256 x) internal pure returns (uint256 result) {\n unchecked {\n // 1e36 is SCALE * SCALE.\n result = 1e36 / x;\n }\n }\n\n /// @notice Calculates the natural logarithm of x.\n ///\n /// @dev Based on the insight that ln(x) = log2(x) / log2(e).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n /// - This doesn't return exactly 1 for 2718281828459045235, for that we would need more fine-grained precision.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm.\n /// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number.\n function ln(uint256 x) internal pure returns (uint256 result) {\n // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)\n // can return is 196205294292027477728.\n unchecked { result = (log2(x) * SCALE) / LOG2_E; }\n }\n\n /// @notice Calculates the common logarithm of x.\n ///\n /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common\n /// logarithm based on the insight that log10(x) = log2(x) / log2(10).\n ///\n /// Requirements:\n /// - All from \"log2\".\n ///\n /// Caveats:\n /// - All from \"log2\".\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm.\n /// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number.\n function log10(uint256 x) internal pure returns (uint256 result) {\n require(x >= SCALE);\n\n // Note that the \"mul\" in this block is the assembly mul operation, not the \"mul\" function defined in this contract.\n // prettier-ignore\n assembly {\n switch x\n case 1 { result := mul(SCALE, sub(0, 18)) }\n case 10 { result := mul(SCALE, sub(1, 18)) }\n case 100 { result := mul(SCALE, sub(2, 18)) }\n case 1000 { result := mul(SCALE, sub(3, 18)) }\n case 10000 { result := mul(SCALE, sub(4, 18)) }\n case 100000 { result := mul(SCALE, sub(5, 18)) }\n case 1000000 { result := mul(SCALE, sub(6, 18)) }\n case 10000000 { result := mul(SCALE, sub(7, 18)) }\n case 100000000 { result := mul(SCALE, sub(8, 18)) }\n case 1000000000 { result := mul(SCALE, sub(9, 18)) }\n case 10000000000 { result := mul(SCALE, sub(10, 18)) }\n case 100000000000 { result := mul(SCALE, sub(11, 18)) }\n case 1000000000000 { result := mul(SCALE, sub(12, 18)) }\n case 10000000000000 { result := mul(SCALE, sub(13, 18)) }\n case 100000000000000 { result := mul(SCALE, sub(14, 18)) }\n case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }\n case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }\n case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := SCALE }\n case 100000000000000000000 { result := mul(SCALE, 2) }\n case 1000000000000000000000 { result := mul(SCALE, 3) }\n case 10000000000000000000000 { result := mul(SCALE, 4) }\n case 100000000000000000000000 { result := mul(SCALE, 5) }\n case 1000000000000000000000000 { result := mul(SCALE, 6) }\n case 10000000000000000000000000 { result := mul(SCALE, 7) }\n case 100000000000000000000000000 { result := mul(SCALE, 8) }\n case 1000000000000000000000000000 { result := mul(SCALE, 9) }\n case 10000000000000000000000000000 { result := mul(SCALE, 10) }\n case 100000000000000000000000000000 { result := mul(SCALE, 11) }\n case 1000000000000000000000000000000 { result := mul(SCALE, 12) }\n case 10000000000000000000000000000000 { result := mul(SCALE, 13) }\n case 100000000000000000000000000000000 { result := mul(SCALE, 14) }\n case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }\n case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }\n case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }\n case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }\n case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }\n case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) }\n default {\n result := MAX_UD60x18\n }\n }\n\n if (result == MAX_UD60x18) {\n // Do the fixed-point division inline to save gas. The denominator is log2(10).\n unchecked { result = (log2(x) * SCALE) / 332192809488736234; }\n }\n }\n\n /// @notice Calculates the binary logarithm of x.\n ///\n /// @dev Based on the iterative approximation algorithm.\n /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n ///\n /// Requirements:\n /// - x must be greater than or equal to SCALE, otherwise the result would be negative.\n ///\n /// Caveats:\n /// - The results are nor perfectly accurate to the last digit, due to the lossy precision of the iterative approximation.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm.\n /// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number.\n function log2(uint256 x) internal pure returns (uint256 result) {\n require(x >= SCALE);\n unchecked {\n // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).\n uint256 n = PRBMathCommon.mostSignificantBit(x / SCALE);\n\n // The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow\n // because n is maximum 255 and SCALE is 1e18.\n result = n * SCALE;\n\n // This is y = x * 2^(-n).\n uint256 y = x >> n;\n\n // If y = 1, the fractional part is zero.\n if (y == SCALE) {\n return result;\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The \"delta >>= 1\" part is equivalent to \"delta /= 2\", but shifting bits is faster.\n for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) {\n y = (y * y) / SCALE;\n\n // Is y^2 > 2 and so in the range [2,4)?\n if (y >= 2 * SCALE) {\n // Add the 2^(-m) factor to the logarithm.\n result += delta;\n\n // Corresponds to z/2 on Wikipedia.\n y >>= 1;\n }\n }\n }\n }\n\n /// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal\n /// fixed-point number.\n /// @dev See the documentation for the \"PRBMathCommon.mulDivFixedPoint\" function.\n /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function mul(uint256 x, uint256 y) internal pure returns (uint256 result) {\n result = PRBMathCommon.mulDivFixedPoint(x, y);\n }\n\n /// @notice Retrieves PI as an unsigned 60.18-decimal fixed-point number.\n function pi() internal pure returns (uint256 result) {\n result = 3141592653589793238;\n }\n\n /// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the\n /// famous algorithm \"exponentiation by squaring\".\n ///\n /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring\n ///\n /// Requirements:\n /// - The result must fit within MAX_UD60x18.\n ///\n /// Caveats:\n /// - All from \"mul\".\n /// - Assumes 0^0 is 1.\n ///\n /// @param x The base as an unsigned 60.18-decimal fixed-point number.\n /// @param y The exponent as an uint256.\n /// @return result The result as an unsigned 60.18-decimal fixed-point number.\n function pow(uint256 x, uint256 y) internal pure returns (uint256 result) {\n // Calculate the first iteration of the loop in advance.\n result = y & 1 > 0 ? x : SCALE;\n\n // Equivalent to \"for(y /= 2; y > 0; y /= 2)\" but faster.\n for (y >>= 1; y > 0; y >>= 1) {\n x = PRBMathCommon.mulDivFixedPoint(x, x);\n\n // Equivalent to \"y % 2 == 1\" but faster.\n if (y & 1 > 0) {\n result = PRBMathCommon.mulDivFixedPoint(result, x);\n }\n }\n }\n\n /// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number.\n function scale() internal pure returns (uint256 result) {\n result = SCALE;\n }\n\n /// @notice Calculates the square root of x, rounding down.\n /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n ///\n /// Requirements:\n /// - x must be less than MAX_UD60x18 / SCALE.\n ///\n /// Caveats:\n /// - The maximum fixed-point number permitted is 115792089237316195423570985008687907853269.984665640564039458.\n ///\n /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root.\n /// @return result The result as an unsigned 60.18-decimal fixed-point .\n function sqrt(uint256 x) internal pure returns (uint256 result) {\n require(x < 115792089237316195423570985008687907853269984665640564039458);\n unchecked {\n // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned\n // 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).\n result = PRBMathCommon.sqrt(x * SCALE);\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils.sol b/examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils.sol new file mode 100644 index 00000000..4dff7f91 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils.sol @@ -0,0 +1,725 @@ +/* + * @title String & slice utility library for Solidity contracts. + * @author Nick Johnson + * + * @dev Functionality in this library is largely implemented using an + * abstraction called a 'slice'. A slice represents a part of a string - + * anything from the entire string to a single character, or even no + * characters at all (a 0-length slice). Since a slice only has to specify + * an offset and a length, copying and manipulating slices is a lot less + * expensive than copying and manipulating the strings they reference. + * + * To further reduce gas costs, most functions on slice that need to return + * a slice modify the original one instead of allocating a new one; for + * instance, `s.split(".")` will return the text up to the first '.', + * modifying s to only contain the remainder of the string after the '.'. + * In situations where you do not want to modify the original slice, you + * can make a copy first with `.copy()`, for example: + * `s.copy().split(".")`. Try and avoid using this idiom in loops; since + * Solidity has no memory management, it will result in allocating many + * short-lived slices that are later discarded. + * + * Functions that return two slices come in two versions: a non-allocating + * version that takes the second slice as an argument, modifying it in + * place, and an allocating version that allocates and returns the second + * slice; see `nextRune` for example. + * + * Functions that have to copy string data will return strings rather than + * slices; these can be cast back to slices for further processing if + * required. + * + * For convenience, some functions are provided with non-modifying + * variants that create a new slice and return both; for instance, + * `s.splitNew('.')` leaves s unmodified, and returns two values + * corresponding to the left and right parts of the string. + */ + +pragma solidity >=0.0; + +library strings { + struct slice { + uint _len; + uint _ptr; + } + + function memcpy(uint dest, uint src, uint len) private pure { + // Copy word-length chunks while possible + for(; len >= 32; len -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + // The following masking would overflow in the case of len=0 + // and the code path in that case is useless, albeit correct. + // This shortcut avoids it and saves gas. + if (len == 0) + return; + + // Copy remaining bytes + uint mask; + unchecked { mask = 256 ** (32 - len) - 1; } + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + /* + * @dev Returns a slice containing the entire string. + * @param self The string to make a slice from. + * @return A newly allocated slice containing the entire string. + */ + function toSlice(string memory self) internal pure returns (slice memory) { + uint ptr; + assembly { + ptr := add(self, 0x20) + } + return slice(bytes(self).length, ptr); + } + + /* + * @dev Returns the length of a null-terminated bytes32 string. + * @param self The value to find the length of. + * @return The length of the string, from 0 to 32. + */ + function len(bytes32 self) internal pure returns (uint) { + uint ret; + if (self == 0) + return 0; + if (uint256(self) & 0xffffffffffffffffffffffffffffffff == 0) { + ret += 16; + self = bytes32(uint(self) / 0x100000000000000000000000000000000); + } + if (uint256(self) & 0xffffffffffffffff == 0) { + ret += 8; + self = bytes32(uint(self) / 0x10000000000000000); + } + if (uint256(self) & 0xffffffff == 0) { + ret += 4; + self = bytes32(uint(self) / 0x100000000); + } + if (uint256(self) & 0xffff == 0) { + ret += 2; + self = bytes32(uint(self) / 0x10000); + } + if (uint256(self) & 0xff == 0) { + ret += 1; + } + return 32 - ret; + } + + /* + * @dev Returns a slice containing the entire bytes32, interpreted as a + * null-terminated utf-8 string. + * @param self The bytes32 value to convert to a slice. + * @return A new slice containing the value of the input argument up to the + * first null. + */ + function toSliceB32(bytes32 self) internal pure returns (slice memory ret) { + // Allocate space for `self` in memory, copy it there, and point ret at it + assembly { + let ptr := mload(0x40) + mstore(0x40, add(ptr, 0x20)) + mstore(ptr, self) + mstore(add(ret, 0x20), ptr) + } + ret._len = len(self); + } + + /* + * @dev Returns a new slice containing the same data as the current slice. + * @param self The slice to copy. + * @return A new slice containing the same data as `self`. + */ + function copy(slice memory self) internal pure returns (slice memory) { + return slice(self._len, self._ptr); + } + + /* + * @dev Copies a slice to a new string. + * @param self The slice to copy. + * @return A newly allocated string containing the slice's text. + */ + function toString(slice memory self) internal pure returns (string memory) { + string memory ret = new string(self._len); + uint retptr; + assembly { retptr := add(ret, 32) } + + memcpy(retptr, self._ptr, self._len); + return ret; + } + + /* + * @dev Returns the length in runes of the slice. Note that this operation + * takes time proportional to the length of the slice; avoid using it + * in loops, and call `slice.empty()` if you only need to know whether + * the slice is empty or not. + * @param self The slice to operate on. + * @return The length of the slice in runes. + */ + function len(slice memory self) internal pure returns (uint l) { + // Starting at ptr-31 means the LSB will be the byte we care about + uint ptr = self._ptr - 31; + uint end = ptr + self._len; + for (l = 0; ptr < end; l++) { + uint8 b; + assembly { b := and(mload(ptr), 0xFF) } + if (b < 0x80) { + ptr += 1; + } else if(b < 0xE0) { + ptr += 2; + } else if(b < 0xF0) { + ptr += 3; + } else if(b < 0xF8) { + ptr += 4; + } else if(b < 0xFC) { + ptr += 5; + } else { + ptr += 6; + } + } + } + + /* + * @dev Returns true if the slice is empty (has a length of 0). + * @param self The slice to operate on. + * @return True if the slice is empty, False otherwise. + */ + function empty(slice memory self) internal pure returns (bool) { + return self._len == 0; + } + + /* + * @dev Returns a positive number if `other` comes lexicographically after + * `self`, a negative number if it comes before, or zero if the + * contents of the two slices are equal. Comparison is done per-rune, + * on unicode codepoints. + * @param self The first slice to compare. + * @param other The second slice to compare. + * @return The result of the comparison. + */ + function compare(slice memory self, slice memory other) internal pure returns (int) { + uint shortest = self._len; + if (other._len < self._len) + shortest = other._len; + + uint selfptr = self._ptr; + uint otherptr = other._ptr; + for (uint idx = 0; idx < shortest; idx += 32) { + uint a; + uint b; + assembly { + a := mload(selfptr) + b := mload(otherptr) + } + if (a != b) { + // Mask out irrelevant bytes and check again + uint256 mask = type(uint256).max; // 0xffff... + if(shortest < 32) { + mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); + } + uint256 diff; + // This depends on potential underflow. + unchecked { diff = (a & mask) - (b & mask); } + if (diff != 0) + return int(diff); + } + selfptr += 32; + otherptr += 32; + } + return int(self._len) - int(other._len); + } + + /* + * @dev Returns true if the two slices contain the same text. + * @param self The first slice to compare. + * @param self The second slice to compare. + * @return True if the slices are equal, false otherwise. + */ + function equals(slice memory self, slice memory other) internal pure returns (bool) { + return compare(self, other) == 0; + } + + /* + * @dev Extracts the first rune in the slice into `rune`, advancing the + * slice to point to the next rune and returning `self`. + * @param self The slice to operate on. + * @param rune The slice that will contain the first rune. + * @return `rune`. + */ + function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) { + rune._ptr = self._ptr; + + if (self._len == 0) { + rune._len = 0; + return rune; + } + + uint l; + uint b; + // Load the first byte of the rune into the LSBs of b + assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) } + if (b < 0x80) { + l = 1; + } else if(b < 0xE0) { + l = 2; + } else if(b < 0xF0) { + l = 3; + } else { + l = 4; + } + + // Check for truncated codepoints + if (l > self._len) { + rune._len = self._len; + self._ptr += self._len; + self._len = 0; + return rune; + } + + self._ptr += l; + self._len -= l; + rune._len = l; + return rune; + } + + /* + * @dev Returns the first rune in the slice, advancing the slice to point + * to the next rune. + * @param self The slice to operate on. + * @return A slice containing only the first rune from `self`. + */ + function nextRune(slice memory self) internal pure returns (slice memory ret) { + nextRune(self, ret); + } + + /* + * @dev Returns the number of the first codepoint in the slice. + * @param self The slice to operate on. + * @return The number of the first codepoint in the slice. + */ + function ord(slice memory self) internal pure returns (uint ret) { + if (self._len == 0) { + return 0; + } + + uint word; + uint length; + uint divisor = 2 ** 248; + + // Load the rune into the MSBs of b + assembly { word:= mload(mload(add(self, 32))) } + uint b = word / divisor; + if (b < 0x80) { + ret = b; + length = 1; + } else if(b < 0xE0) { + ret = b & 0x1F; + length = 2; + } else if(b < 0xF0) { + ret = b & 0x0F; + length = 3; + } else { + ret = b & 0x07; + length = 4; + } + + // Check for truncated codepoints + if (length > self._len) { + return 0; + } + + for (uint i = 1; i < length; i++) { + divisor = divisor / 256; + b = (word / divisor) & 0xFF; + if (b & 0xC0 != 0x80) { + // Invalid UTF-8 sequence + return 0; + } + ret = (ret * 64) | (b & 0x3F); + } + + return ret; + } + + /* + * @dev Returns the keccak-256 hash of the slice. + * @param self The slice to hash. + * @return The hash of the slice. + */ + function keccak(slice memory self) internal pure returns (bytes32 ret) { + assembly { + ret := keccak256(mload(add(self, 32)), mload(self)) + } + } + + /* + * @dev Returns true if `self` starts with `needle`. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return True if the slice starts with the provided text, false otherwise. + */ + function startsWith(slice memory self, slice memory needle) internal pure returns (bool) { + if (self._len < needle._len) { + return false; + } + + if (self._ptr == needle._ptr) { + return true; + } + + bool equal; + assembly { + let length := mload(needle) + let selfptr := mload(add(self, 0x20)) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + return equal; + } + + /* + * @dev If `self` starts with `needle`, `needle` is removed from the + * beginning of `self`. Otherwise, `self` is unmodified. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return `self` + */ + function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) { + if (self._len < needle._len) { + return self; + } + + bool equal = true; + if (self._ptr != needle._ptr) { + assembly { + let length := mload(needle) + let selfptr := mload(add(self, 0x20)) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + } + + if (equal) { + self._len -= needle._len; + self._ptr += needle._len; + } + + return self; + } + + /* + * @dev Returns true if the slice ends with `needle`. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return True if the slice starts with the provided text, false otherwise. + */ + function endsWith(slice memory self, slice memory needle) internal pure returns (bool) { + if (self._len < needle._len) { + return false; + } + + uint selfptr = self._ptr + self._len - needle._len; + + if (selfptr == needle._ptr) { + return true; + } + + bool equal; + assembly { + let length := mload(needle) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + + return equal; + } + + /* + * @dev If `self` ends with `needle`, `needle` is removed from the + * end of `self`. Otherwise, `self` is unmodified. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return `self` + */ + function until(slice memory self, slice memory needle) internal pure returns (slice memory) { + if (self._len < needle._len) { + return self; + } + + uint selfptr = self._ptr + self._len - needle._len; + bool equal = true; + if (selfptr != needle._ptr) { + assembly { + let length := mload(needle) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + } + + if (equal) { + self._len -= needle._len; + } + + return self; + } + + // Returns the memory address of the first byte of the first occurrence of + // `needle` in `self`, or the first byte after `self` if not found. + function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { + uint ptr = selfptr; + uint idx; + + if (needlelen <= selflen) { + if (needlelen <= 32) { + bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); + + bytes32 needledata; + assembly { needledata := and(mload(needleptr), mask) } + + uint end = selfptr + selflen - needlelen; + bytes32 ptrdata; + assembly { ptrdata := and(mload(ptr), mask) } + + while (ptrdata != needledata) { + if (ptr >= end) + return selfptr + selflen; + ptr++; + assembly { ptrdata := and(mload(ptr), mask) } + } + return ptr; + } else { + // For long needles, use hashing + bytes32 hash; + assembly { hash := keccak256(needleptr, needlelen) } + + for (idx = 0; idx <= selflen - needlelen; idx++) { + bytes32 testHash; + assembly { testHash := keccak256(ptr, needlelen) } + if (hash == testHash) + return ptr; + ptr += 1; + } + } + } + return selfptr + selflen; + } + + // Returns the memory address of the first byte after the last occurrence of + // `needle` in `self`, or the address of `self` if not found. + function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { + uint ptr; + + if (needlelen <= selflen) { + if (needlelen <= 32) { + bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); + + bytes32 needledata; + assembly { needledata := and(mload(needleptr), mask) } + + ptr = selfptr + selflen - needlelen; + bytes32 ptrdata; + assembly { ptrdata := and(mload(ptr), mask) } + + while (ptrdata != needledata) { + if (ptr <= selfptr) + return selfptr; + ptr--; + assembly { ptrdata := and(mload(ptr), mask) } + } + return ptr + needlelen; + } else { + // For long needles, use hashing + bytes32 hash; + assembly { hash := keccak256(needleptr, needlelen) } + ptr = selfptr + (selflen - needlelen); + while (ptr >= selfptr) { + bytes32 testHash; + assembly { testHash := keccak256(ptr, needlelen) } + if (hash == testHash) + return ptr + needlelen; + ptr -= 1; + } + } + } + return selfptr; + } + + /* + * @dev Modifies `self` to contain everything from the first occurrence of + * `needle` to the end of the slice. `self` is set to the empty slice + * if `needle` is not found. + * @param self The slice to search and modify. + * @param needle The text to search for. + * @return `self`. + */ + function find(slice memory self, slice memory needle) internal pure returns (slice memory) { + uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); + self._len -= ptr - self._ptr; + self._ptr = ptr; + return self; + } + + /* + * @dev Modifies `self` to contain the part of the string from the start of + * `self` to the end of the first occurrence of `needle`. If `needle` + * is not found, `self` is set to the empty slice. + * @param self The slice to search and modify. + * @param needle The text to search for. + * @return `self`. + */ + function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) { + uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); + self._len = ptr - self._ptr; + return self; + } + + /* + * @dev Splits the slice, setting `self` to everything after the first + * occurrence of `needle`, and `token` to everything before it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and `token` is set to the entirety of `self`. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @param token An output parameter to which the first token is written. + * @return `token`. + */ + function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { + uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); + token._ptr = self._ptr; + token._len = ptr - self._ptr; + if (ptr == self._ptr + self._len) { + // Not found + self._len = 0; + } else { + self._len -= token._len + needle._len; + self._ptr = ptr + needle._len; + } + return token; + } + + /* + * @dev Splits the slice, setting `self` to everything after the first + * occurrence of `needle`, and returning everything before it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and the entirety of `self` is returned. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @return The part of `self` up to the first occurrence of `delim`. + */ + function split(slice memory self, slice memory needle) internal pure returns (slice memory token) { + split(self, needle, token); + } + + /* + * @dev Splits the slice, setting `self` to everything before the last + * occurrence of `needle`, and `token` to everything after it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and `token` is set to the entirety of `self`. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @param token An output parameter to which the first token is written. + * @return `token`. + */ + function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { + uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); + token._ptr = ptr; + token._len = self._len - (ptr - self._ptr); + if (ptr == self._ptr) { + // Not found + self._len = 0; + } else { + self._len -= token._len + needle._len; + } + return token; + } + + /* + * @dev Splits the slice, setting `self` to everything before the last + * occurrence of `needle`, and returning everything after it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and the entirety of `self` is returned. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @return The part of `self` after the last occurrence of `delim`. + */ + function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) { + rsplit(self, needle, token); + } + + /* + * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`. + * @param self The slice to search. + * @param needle The text to search for in `self`. + * @return The number of occurrences of `needle` found in `self`. + */ + function count(slice memory self, slice memory needle) internal pure returns (uint cnt) { + uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len; + while (ptr <= self._ptr + self._len) { + cnt++; + ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len; + } + } + + /* + * @dev Returns True if `self` contains `needle`. + * @param self The slice to search. + * @param needle The text to search for in `self`. + * @return True if `needle` is found in `self`, false otherwise. + */ + function contains(slice memory self, slice memory needle) internal pure returns (bool) { + return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr; + } + + /* + * @dev Returns a newly allocated string containing the concatenation of + * `self` and `other`. + * @param self The first slice to concatenate. + * @param other The second slice to concatenate. + * @return The concatenation of the two strings. + */ + function concat(slice memory self, slice memory other) internal pure returns (string memory) { + string memory ret = new string(self._len + other._len); + uint retptr; + assembly { retptr := add(ret, 32) } + memcpy(retptr, self._ptr, self._len); + memcpy(retptr + self._len, other._ptr, other._len); + return ret; + } + + /* + * @dev Joins an array of slices, using `self` as a delimiter, returning a + * newly allocated string. + * @param self The delimiter to use. + * @param parts A list of slices to join. + * @return A newly allocated string containing all the slices in `parts`, + * joined with `self`. + */ + function join(slice memory self, slice[] memory parts) internal pure returns (string memory) { + if (parts.length == 0) + return ""; + + uint length = self._len * (parts.length - 1); + for(uint i = 0; i < parts.length; i++) + length += parts[i]._len; + + string memory ret = new string(length); + uint retptr; + assembly { retptr := add(ret, 32) } + + for(uint i = 0; i < parts.length; i++) { + memcpy(retptr, parts[i]._ptr, parts[i]._len); + retptr += parts[i]._len; + if (i < parts.length - 1) { + memcpy(retptr, self._ptr, self._len); + retptr += self._len; + } + } + + return ret; + } +} diff --git a/examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils_standard_input.json b/examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils_standard_input.json new file mode 100644 index 00000000..5f419d98 --- /dev/null +++ b/examples/test/semanticTests/externalContracts__stringutils_stringutils/stringutils_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "stringutils.sol": { + "content": "/*\n * @title String & slice utility library for Solidity contracts.\n * @author Nick Johnson \n *\n * @dev Functionality in this library is largely implemented using an\n * abstraction called a 'slice'. A slice represents a part of a string -\n * anything from the entire string to a single character, or even no\n * characters at all (a 0-length slice). Since a slice only has to specify\n * an offset and a length, copying and manipulating slices is a lot less\n * expensive than copying and manipulating the strings they reference.\n *\n * To further reduce gas costs, most functions on slice that need to return\n * a slice modify the original one instead of allocating a new one; for\n * instance, `s.split(\".\")` will return the text up to the first '.',\n * modifying s to only contain the remainder of the string after the '.'.\n * In situations where you do not want to modify the original slice, you\n * can make a copy first with `.copy()`, for example:\n * `s.copy().split(\".\")`. Try and avoid using this idiom in loops; since\n * Solidity has no memory management, it will result in allocating many\n * short-lived slices that are later discarded.\n *\n * Functions that return two slices come in two versions: a non-allocating\n * version that takes the second slice as an argument, modifying it in\n * place, and an allocating version that allocates and returns the second\n * slice; see `nextRune` for example.\n *\n * Functions that have to copy string data will return strings rather than\n * slices; these can be cast back to slices for further processing if\n * required.\n *\n * For convenience, some functions are provided with non-modifying\n * variants that create a new slice and return both; for instance,\n * `s.splitNew('.')` leaves s unmodified, and returns two values\n * corresponding to the left and right parts of the string.\n */\n\npragma solidity >=0.0;\n\nlibrary strings {\n struct slice {\n uint _len;\n uint _ptr;\n }\n\n function memcpy(uint dest, uint src, uint len) private pure {\n // Copy word-length chunks while possible\n for(; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n // The following masking would overflow in the case of len=0\n // and the code path in that case is useless, albeit correct.\n // This shortcut avoids it and saves gas.\n if (len == 0)\n return;\n\n // Copy remaining bytes\n uint mask;\n unchecked { mask = 256 ** (32 - len) - 1; }\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n /*\n * @dev Returns a slice containing the entire string.\n * @param self The string to make a slice from.\n * @return A newly allocated slice containing the entire string.\n */\n function toSlice(string memory self) internal pure returns (slice memory) {\n uint ptr;\n assembly {\n ptr := add(self, 0x20)\n }\n return slice(bytes(self).length, ptr);\n }\n\n /*\n * @dev Returns the length of a null-terminated bytes32 string.\n * @param self The value to find the length of.\n * @return The length of the string, from 0 to 32.\n */\n function len(bytes32 self) internal pure returns (uint) {\n uint ret;\n if (self == 0)\n return 0;\n if (uint256(self) & 0xffffffffffffffffffffffffffffffff == 0) {\n ret += 16;\n self = bytes32(uint(self) / 0x100000000000000000000000000000000);\n }\n if (uint256(self) & 0xffffffffffffffff == 0) {\n ret += 8;\n self = bytes32(uint(self) / 0x10000000000000000);\n }\n if (uint256(self) & 0xffffffff == 0) {\n ret += 4;\n self = bytes32(uint(self) / 0x100000000);\n }\n if (uint256(self) & 0xffff == 0) {\n ret += 2;\n self = bytes32(uint(self) / 0x10000);\n }\n if (uint256(self) & 0xff == 0) {\n ret += 1;\n }\n return 32 - ret;\n }\n\n /*\n * @dev Returns a slice containing the entire bytes32, interpreted as a\n * null-terminated utf-8 string.\n * @param self The bytes32 value to convert to a slice.\n * @return A new slice containing the value of the input argument up to the\n * first null.\n */\n function toSliceB32(bytes32 self) internal pure returns (slice memory ret) {\n // Allocate space for `self` in memory, copy it there, and point ret at it\n assembly {\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, 0x20))\n mstore(ptr, self)\n mstore(add(ret, 0x20), ptr)\n }\n ret._len = len(self);\n }\n\n /*\n * @dev Returns a new slice containing the same data as the current slice.\n * @param self The slice to copy.\n * @return A new slice containing the same data as `self`.\n */\n function copy(slice memory self) internal pure returns (slice memory) {\n return slice(self._len, self._ptr);\n }\n\n /*\n * @dev Copies a slice to a new string.\n * @param self The slice to copy.\n * @return A newly allocated string containing the slice's text.\n */\n function toString(slice memory self) internal pure returns (string memory) {\n string memory ret = new string(self._len);\n uint retptr;\n assembly { retptr := add(ret, 32) }\n\n memcpy(retptr, self._ptr, self._len);\n return ret;\n }\n\n /*\n * @dev Returns the length in runes of the slice. Note that this operation\n * takes time proportional to the length of the slice; avoid using it\n * in loops, and call `slice.empty()` if you only need to know whether\n * the slice is empty or not.\n * @param self The slice to operate on.\n * @return The length of the slice in runes.\n */\n function len(slice memory self) internal pure returns (uint l) {\n // Starting at ptr-31 means the LSB will be the byte we care about\n uint ptr = self._ptr - 31;\n uint end = ptr + self._len;\n for (l = 0; ptr < end; l++) {\n uint8 b;\n assembly { b := and(mload(ptr), 0xFF) }\n if (b < 0x80) {\n ptr += 1;\n } else if(b < 0xE0) {\n ptr += 2;\n } else if(b < 0xF0) {\n ptr += 3;\n } else if(b < 0xF8) {\n ptr += 4;\n } else if(b < 0xFC) {\n ptr += 5;\n } else {\n ptr += 6;\n }\n }\n }\n\n /*\n * @dev Returns true if the slice is empty (has a length of 0).\n * @param self The slice to operate on.\n * @return True if the slice is empty, False otherwise.\n */\n function empty(slice memory self) internal pure returns (bool) {\n return self._len == 0;\n }\n\n /*\n * @dev Returns a positive number if `other` comes lexicographically after\n * `self`, a negative number if it comes before, or zero if the\n * contents of the two slices are equal. Comparison is done per-rune,\n * on unicode codepoints.\n * @param self The first slice to compare.\n * @param other The second slice to compare.\n * @return The result of the comparison.\n */\n function compare(slice memory self, slice memory other) internal pure returns (int) {\n uint shortest = self._len;\n if (other._len < self._len)\n shortest = other._len;\n\n uint selfptr = self._ptr;\n uint otherptr = other._ptr;\n for (uint idx = 0; idx < shortest; idx += 32) {\n uint a;\n uint b;\n assembly {\n a := mload(selfptr)\n b := mload(otherptr)\n }\n if (a != b) {\n // Mask out irrelevant bytes and check again\n uint256 mask = type(uint256).max; // 0xffff...\n if(shortest < 32) {\n mask = ~(2 ** (8 * (32 - shortest + idx)) - 1);\n }\n uint256 diff;\n // This depends on potential underflow.\n unchecked { diff = (a & mask) - (b & mask); }\n if (diff != 0)\n return int(diff);\n }\n selfptr += 32;\n otherptr += 32;\n }\n return int(self._len) - int(other._len);\n }\n\n /*\n * @dev Returns true if the two slices contain the same text.\n * @param self The first slice to compare.\n * @param self The second slice to compare.\n * @return True if the slices are equal, false otherwise.\n */\n function equals(slice memory self, slice memory other) internal pure returns (bool) {\n return compare(self, other) == 0;\n }\n\n /*\n * @dev Extracts the first rune in the slice into `rune`, advancing the\n * slice to point to the next rune and returning `self`.\n * @param self The slice to operate on.\n * @param rune The slice that will contain the first rune.\n * @return `rune`.\n */\n function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) {\n rune._ptr = self._ptr;\n\n if (self._len == 0) {\n rune._len = 0;\n return rune;\n }\n\n uint l;\n uint b;\n // Load the first byte of the rune into the LSBs of b\n assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) }\n if (b < 0x80) {\n l = 1;\n } else if(b < 0xE0) {\n l = 2;\n } else if(b < 0xF0) {\n l = 3;\n } else {\n l = 4;\n }\n\n // Check for truncated codepoints\n if (l > self._len) {\n rune._len = self._len;\n self._ptr += self._len;\n self._len = 0;\n return rune;\n }\n\n self._ptr += l;\n self._len -= l;\n rune._len = l;\n return rune;\n }\n\n /*\n * @dev Returns the first rune in the slice, advancing the slice to point\n * to the next rune.\n * @param self The slice to operate on.\n * @return A slice containing only the first rune from `self`.\n */\n function nextRune(slice memory self) internal pure returns (slice memory ret) {\n nextRune(self, ret);\n }\n\n /*\n * @dev Returns the number of the first codepoint in the slice.\n * @param self The slice to operate on.\n * @return The number of the first codepoint in the slice.\n */\n function ord(slice memory self) internal pure returns (uint ret) {\n if (self._len == 0) {\n return 0;\n }\n\n uint word;\n uint length;\n uint divisor = 2 ** 248;\n\n // Load the rune into the MSBs of b\n assembly { word:= mload(mload(add(self, 32))) }\n uint b = word / divisor;\n if (b < 0x80) {\n ret = b;\n length = 1;\n } else if(b < 0xE0) {\n ret = b & 0x1F;\n length = 2;\n } else if(b < 0xF0) {\n ret = b & 0x0F;\n length = 3;\n } else {\n ret = b & 0x07;\n length = 4;\n }\n\n // Check for truncated codepoints\n if (length > self._len) {\n return 0;\n }\n\n for (uint i = 1; i < length; i++) {\n divisor = divisor / 256;\n b = (word / divisor) & 0xFF;\n if (b & 0xC0 != 0x80) {\n // Invalid UTF-8 sequence\n return 0;\n }\n ret = (ret * 64) | (b & 0x3F);\n }\n\n return ret;\n }\n\n /*\n * @dev Returns the keccak-256 hash of the slice.\n * @param self The slice to hash.\n * @return The hash of the slice.\n */\n function keccak(slice memory self) internal pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(mload(add(self, 32)), mload(self))\n }\n }\n\n /*\n * @dev Returns true if `self` starts with `needle`.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return True if the slice starts with the provided text, false otherwise.\n */\n function startsWith(slice memory self, slice memory needle) internal pure returns (bool) {\n if (self._len < needle._len) {\n return false;\n }\n\n if (self._ptr == needle._ptr) {\n return true;\n }\n\n bool equal;\n assembly {\n let length := mload(needle)\n let selfptr := mload(add(self, 0x20))\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n return equal;\n }\n\n /*\n * @dev If `self` starts with `needle`, `needle` is removed from the\n * beginning of `self`. Otherwise, `self` is unmodified.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return `self`\n */\n function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) {\n if (self._len < needle._len) {\n return self;\n }\n\n bool equal = true;\n if (self._ptr != needle._ptr) {\n assembly {\n let length := mload(needle)\n let selfptr := mload(add(self, 0x20))\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n }\n\n if (equal) {\n self._len -= needle._len;\n self._ptr += needle._len;\n }\n\n return self;\n }\n\n /*\n * @dev Returns true if the slice ends with `needle`.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return True if the slice starts with the provided text, false otherwise.\n */\n function endsWith(slice memory self, slice memory needle) internal pure returns (bool) {\n if (self._len < needle._len) {\n return false;\n }\n\n uint selfptr = self._ptr + self._len - needle._len;\n\n if (selfptr == needle._ptr) {\n return true;\n }\n\n bool equal;\n assembly {\n let length := mload(needle)\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n\n return equal;\n }\n\n /*\n * @dev If `self` ends with `needle`, `needle` is removed from the\n * end of `self`. Otherwise, `self` is unmodified.\n * @param self The slice to operate on.\n * @param needle The slice to search for.\n * @return `self`\n */\n function until(slice memory self, slice memory needle) internal pure returns (slice memory) {\n if (self._len < needle._len) {\n return self;\n }\n\n uint selfptr = self._ptr + self._len - needle._len;\n bool equal = true;\n if (selfptr != needle._ptr) {\n assembly {\n let length := mload(needle)\n let needleptr := mload(add(needle, 0x20))\n equal := eq(keccak256(selfptr, length), keccak256(needleptr, length))\n }\n }\n\n if (equal) {\n self._len -= needle._len;\n }\n\n return self;\n }\n\n // Returns the memory address of the first byte of the first occurrence of\n // `needle` in `self`, or the first byte after `self` if not found.\n function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {\n uint ptr = selfptr;\n uint idx;\n\n if (needlelen <= selflen) {\n if (needlelen <= 32) {\n bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));\n\n bytes32 needledata;\n assembly { needledata := and(mload(needleptr), mask) }\n\n uint end = selfptr + selflen - needlelen;\n bytes32 ptrdata;\n assembly { ptrdata := and(mload(ptr), mask) }\n\n while (ptrdata != needledata) {\n if (ptr >= end)\n return selfptr + selflen;\n ptr++;\n assembly { ptrdata := and(mload(ptr), mask) }\n }\n return ptr;\n } else {\n // For long needles, use hashing\n bytes32 hash;\n assembly { hash := keccak256(needleptr, needlelen) }\n\n for (idx = 0; idx <= selflen - needlelen; idx++) {\n bytes32 testHash;\n assembly { testHash := keccak256(ptr, needlelen) }\n if (hash == testHash)\n return ptr;\n ptr += 1;\n }\n }\n }\n return selfptr + selflen;\n }\n\n // Returns the memory address of the first byte after the last occurrence of\n // `needle` in `self`, or the address of `self` if not found.\n function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) {\n uint ptr;\n\n if (needlelen <= selflen) {\n if (needlelen <= 32) {\n bytes32 mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1));\n\n bytes32 needledata;\n assembly { needledata := and(mload(needleptr), mask) }\n\n ptr = selfptr + selflen - needlelen;\n bytes32 ptrdata;\n assembly { ptrdata := and(mload(ptr), mask) }\n\n while (ptrdata != needledata) {\n if (ptr <= selfptr)\n return selfptr;\n ptr--;\n assembly { ptrdata := and(mload(ptr), mask) }\n }\n return ptr + needlelen;\n } else {\n // For long needles, use hashing\n bytes32 hash;\n assembly { hash := keccak256(needleptr, needlelen) }\n ptr = selfptr + (selflen - needlelen);\n while (ptr >= selfptr) {\n bytes32 testHash;\n assembly { testHash := keccak256(ptr, needlelen) }\n if (hash == testHash)\n return ptr + needlelen;\n ptr -= 1;\n }\n }\n }\n return selfptr;\n }\n\n /*\n * @dev Modifies `self` to contain everything from the first occurrence of\n * `needle` to the end of the slice. `self` is set to the empty slice\n * if `needle` is not found.\n * @param self The slice to search and modify.\n * @param needle The text to search for.\n * @return `self`.\n */\n function find(slice memory self, slice memory needle) internal pure returns (slice memory) {\n uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);\n self._len -= ptr - self._ptr;\n self._ptr = ptr;\n return self;\n }\n\n /*\n * @dev Modifies `self` to contain the part of the string from the start of\n * `self` to the end of the first occurrence of `needle`. If `needle`\n * is not found, `self` is set to the empty slice.\n * @param self The slice to search and modify.\n * @param needle The text to search for.\n * @return `self`.\n */\n function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) {\n uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);\n self._len = ptr - self._ptr;\n return self;\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything after the first\n * occurrence of `needle`, and `token` to everything before it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and `token` is set to the entirety of `self`.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @param token An output parameter to which the first token is written.\n * @return `token`.\n */\n function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {\n uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr);\n token._ptr = self._ptr;\n token._len = ptr - self._ptr;\n if (ptr == self._ptr + self._len) {\n // Not found\n self._len = 0;\n } else {\n self._len -= token._len + needle._len;\n self._ptr = ptr + needle._len;\n }\n return token;\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything after the first\n * occurrence of `needle`, and returning everything before it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and the entirety of `self` is returned.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @return The part of `self` up to the first occurrence of `delim`.\n */\n function split(slice memory self, slice memory needle) internal pure returns (slice memory token) {\n split(self, needle, token);\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything before the last\n * occurrence of `needle`, and `token` to everything after it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and `token` is set to the entirety of `self`.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @param token An output parameter to which the first token is written.\n * @return `token`.\n */\n function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) {\n uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr);\n token._ptr = ptr;\n token._len = self._len - (ptr - self._ptr);\n if (ptr == self._ptr) {\n // Not found\n self._len = 0;\n } else {\n self._len -= token._len + needle._len;\n }\n return token;\n }\n\n /*\n * @dev Splits the slice, setting `self` to everything before the last\n * occurrence of `needle`, and returning everything after it. If\n * `needle` does not occur in `self`, `self` is set to the empty slice,\n * and the entirety of `self` is returned.\n * @param self The slice to split.\n * @param needle The text to search for in `self`.\n * @return The part of `self` after the last occurrence of `delim`.\n */\n function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) {\n rsplit(self, needle, token);\n }\n\n /*\n * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`.\n * @param self The slice to search.\n * @param needle The text to search for in `self`.\n * @return The number of occurrences of `needle` found in `self`.\n */\n function count(slice memory self, slice memory needle) internal pure returns (uint cnt) {\n uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len;\n while (ptr <= self._ptr + self._len) {\n cnt++;\n ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len;\n }\n }\n\n /*\n * @dev Returns True if `self` contains `needle`.\n * @param self The slice to search.\n * @param needle The text to search for in `self`.\n * @return True if `needle` is found in `self`, false otherwise.\n */\n function contains(slice memory self, slice memory needle) internal pure returns (bool) {\n return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr;\n }\n\n /*\n * @dev Returns a newly allocated string containing the concatenation of\n * `self` and `other`.\n * @param self The first slice to concatenate.\n * @param other The second slice to concatenate.\n * @return The concatenation of the two strings.\n */\n function concat(slice memory self, slice memory other) internal pure returns (string memory) {\n string memory ret = new string(self._len + other._len);\n uint retptr;\n assembly { retptr := add(ret, 32) }\n memcpy(retptr, self._ptr, self._len);\n memcpy(retptr + self._len, other._ptr, other._len);\n return ret;\n }\n\n /*\n * @dev Joins an array of slices, using `self` as a delimiter, returning a\n * newly allocated string.\n * @param self The delimiter to use.\n * @param parts A list of slices to join.\n * @return A newly allocated string containing all the slices in `parts`,\n * joined with `self`.\n */\n function join(slice memory self, slice[] memory parts) internal pure returns (string memory) {\n if (parts.length == 0)\n return \"\";\n\n uint length = self._len * (parts.length - 1);\n for(uint i = 0; i < parts.length; i++)\n length += parts[i]._len;\n\n string memory ret = new string(length);\n uint retptr;\n assembly { retptr := add(ret, 32) }\n\n for(uint i = 0; i < parts.length; i++) {\n memcpy(retptr, parts[i]._ptr, parts[i]._len);\n retptr += parts[i]._len;\n if (i < parts.length - 1) {\n memcpy(retptr, self._ptr, self._len);\n retptr += self._len;\n }\n }\n\n return ret;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_base64/base64.sol b/examples/test/semanticTests/externalContracts_base64/base64.sol new file mode 100644 index 00000000..6e23da85 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_base64/base64.sol @@ -0,0 +1,63 @@ +==== ExternalSource: _base64/base64_inline_asm.sol ==== +==== ExternalSource: _base64/base64_no_inline_asm.sol ==== +==== Source: base64.sol ==== + +import "_base64/base64_inline_asm.sol"; +import "_base64/base64_no_inline_asm.sol"; + +contract test { + function encode_inline_asm(bytes memory data) external pure returns (string memory) { + return InlineAsmBase64.encode(data); + } + + function encode_no_asm(bytes memory data) external pure returns (string memory) { + return NoAsmBase64.encode(data); + } + + function encode_inline_asm_large() external { + for (uint i = 0; i < 1000; i++) { + InlineAsmBase64.encode("foo"); + } + } + + function encode_no_asm_large() external { + for (uint i = 0; i < 1000; i++) { + NoAsmBase64.encode("foo"); + } + } +} +// Test cases derived from Base64 specification: RFC4648 +// https://datatracker.ietf.org/doc/html/rfc4648#section-10 +// +// ==== +// EVMVersion: >=constantinople +// ---- +// constructor() +// gas irOptimized: 79076 +// gas irOptimized code: 322000 +// gas legacy: 102214 +// gas legacy code: 629800 +// gas legacyOptimized: 87926 +// gas legacyOptimized code: 429800 +// encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0 +// encode_inline_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" +// encode_inline_asm(bytes): 0x20, 2, "fo" -> 0x20, 4, "Zm8=" +// encode_inline_asm(bytes): 0x20, 3, "foo" -> 0x20, 4, "Zm9v" +// encode_inline_asm(bytes): 0x20, 4, "foob" -> 0x20, 8, "Zm9vYg==" +// encode_inline_asm(bytes): 0x20, 5, "fooba" -> 0x20, 8, "Zm9vYmE=" +// encode_inline_asm(bytes): 0x20, 6, "foobar" -> 0x20, 8, "Zm9vYmFy" +// encode_no_asm(bytes): 0x20, 0 -> 0x20, 0 +// encode_no_asm(bytes): 0x20, 1, "f" -> 0x20, 4, "Zg==" +// encode_no_asm(bytes): 0x20, 2, "fo" -> 0x20, 4, "Zm8=" +// encode_no_asm(bytes): 0x20, 3, "foo" -> 0x20, 4, "Zm9v" +// encode_no_asm(bytes): 0x20, 4, "foob" -> 0x20, 8, "Zm9vYg==" +// encode_no_asm(bytes): 0x20, 5, "fooba" -> 0x20, 8, "Zm9vYmE=" +// encode_no_asm(bytes): 0x20, 6, "foobar" -> 0x20, 8, "Zm9vYmFy" +// encode_inline_asm_large() +// gas irOptimized: 1406025 +// gas legacy: 1554038 +// gas legacyOptimized: 1132031 +// encode_no_asm_large() +// gas irOptimized: 3512081 +// gas legacy: 4600082 +// gas legacyOptimized: 2813075 diff --git a/examples/test/semanticTests/externalContracts_base64/base64_standard_input.json b/examples/test/semanticTests/externalContracts_base64/base64_standard_input.json new file mode 100644 index 00000000..7f20a9e7 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_base64/base64_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + }, + "deposit_contract.sol": { + "content": "// \u250f\u2501\u2501\u2501\u2513\u2501\u250f\u2513\u2501\u250f\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\n// \u2503\u250f\u2501\u2501\u251b\u250f\u251b\u2517\u2513\u2503\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2517\u2513\u250f\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\n// \u2503\u2517\u2501\u2501\u2513\u2517\u2513\u250f\u251b\u2503\u2517\u2501\u2513\u2517\u251b\u250f\u251b\u2503\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2513\u2517\u2513\u250f\u251b\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2517\u251b\u250f\u2501\u2501\u2513\u250f\u2501\u2513\u2501\u2517\u2513\u250f\u251b\u250f\u2501\u2513\u250f\u2501\u2501\u2513\u2501\u250f\u2501\u2501\u2513\u2517\u2513\u250f\u251b\n// \u2503\u250f\u2501\u2501\u251b\u2501\u2503\u2503\u2501\u2503\u250f\u2513\u2503\u250f\u2501\u251b\u250f\u251b\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u2501\u2501\u252b\u2523\u252b\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u250f\u2513\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2513\u2501\u2503\u2503\u2501\u2503\u250f\u251b\u2517\u2501\u2513\u2503\u2501\u2503\u250f\u2501\u251b\u2501\u2503\u2503\u2501\n// \u2503\u2517\u2501\u2501\u2513\u2501\u2503\u2517\u2513\u2503\u2503\u2503\u2503\u2503\u2503\u2517\u2501\u2513\u250f\u2513\u2503\u2517\u2501\u251b\u2503\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u251b\u2503\u2503\u2503\u2501\u252b\u2503\u2517\u251b\u2503\u2503\u2517\u251b\u2503\u2523\u2501\u2501\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u2517\u2501\u251b\u2503\u2503\u2517\u251b\u2503\u2503\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2503\u2503\u2501\u2503\u2517\u251b\u2517\u2513\u2503\u2517\u2501\u2513\u2501\u2503\u2517\u2513\n// \u2517\u2501\u2501\u2501\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2503\u250f\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2501\u2517\u2501\u251b\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2517\u251b\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n /// @notice A processed deposit event.\n event DepositEvent(\n bytes pubkey,\n bytes withdrawal_credentials,\n bytes amount,\n bytes signature,\n bytes index\n );\n\n /// @notice Submit a Phase 0 DepositData object.\n /// @param pubkey A BLS12-381 public key.\n /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n /// @param signature A BLS12-381 signature.\n /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n /// Used as a protection against malformed input.\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) external payable;\n\n /// @notice Query the current deposit root hash.\n /// @return The deposit root hash.\n function get_deposit_root() external view returns (bytes32);\n\n /// @notice Query the current deposit count.\n /// @return The deposit count encoded as a little endian 64-bit number.\n function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceId` and\n /// `interfaceId` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n // NOTE: this also ensures `deposit_count` will fit into 64-bits\n uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n uint256 deposit_count;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n constructor() public {\n // Compute hashes in empty sparse Merkle tree\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n }\n\n function get_deposit_root() override external view returns (bytes32) {\n bytes32 node;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1)\n node = sha256(abi.encodePacked(branch[height], node));\n else\n node = sha256(abi.encodePacked(node, zero_hashes[height]));\n size /= 2;\n }\n return sha256(abi.encodePacked(\n node,\n to_little_endian_64(uint64(deposit_count)),\n bytes24(0)\n ));\n }\n\n function get_deposit_count() override external view returns (bytes memory) {\n return to_little_endian_64(uint64(deposit_count));\n }\n\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) override external payable {\n // Extended ABI length checks since dynamic types are used.\n require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n // Check deposit amount\n require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n uint deposit_amount = msg.value / 1 gwei;\n require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n // Emit `DepositEvent` log\n bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n emit DepositEvent(\n pubkey,\n withdrawal_credentials,\n amount,\n signature,\n to_little_endian_64(uint64(deposit_count))\n );\n\n // Compute deposit data root (`DepositData` hash tree root)\n bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n bytes32 signature_root = sha256(abi.encodePacked(\n sha256(abi.encodePacked(signature[:64])),\n sha256(abi.encodePacked(signature[64:], bytes32(0)))\n ));\n bytes32 node = sha256(abi.encodePacked(\n sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n ));\n\n // Verify computed and expected deposit data roots match\n require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n // Add deposit data root to Merkle tree (update a single `branch` node)\n deposit_count += 1;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1) {\n branch[height] = node;\n return;\n }\n node = sha256(abi.encodePacked(branch[height], node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n }\n\n function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n" + }, + "snark.sol": { + "content": "library Pairing {\n\tstruct G1Point {\n\t\tuint X;\n\t\tuint Y;\n\t}\n\t// Encoding of field elements is: X[0] * z + X[1]\n\tstruct G2Point {\n\t\tuint[2] X;\n\t\tuint[2] Y;\n\t}\n\n\t/// @return the generator of G1\n\tfunction P1() internal returns (G1Point memory) {\n\t\treturn G1Point(1, 2);\n\t}\n\n\t/// @return the generator of G2\n\tfunction P2() internal returns (G2Point memory) {\n\t\treturn G2Point(\n\t\t\t[11559732032986387107991004021392285783925812861821192530917403151452391805634,\n\t\t\t 10857046999023057135944570762232829481370756359578518086990519993285655852781],\n\t\t\t[4082367875863433681332203403145435568316851327593401208105741076214120093531,\n\t\t\t 8495653923123431417604973247489272438418190587263600148770280649306958101930]\n\t\t);\n\t}\n\n\t/// @return the negation of p, i.e. p.add(p.negate()) should be zero.\n\tfunction negate(G1Point memory p) internal returns (G1Point memory) {\n\t\t// The prime q in the base field F_q for G1\n\t\tuint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tif (p.X == 0 && p.Y == 0)\n\t\t\treturn G1Point(0, 0);\n\t\treturn G1Point(p.X, q - (p.Y % q));\n\t}\n\n\t/// @return r the sum of two points of G1\n\tfunction add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {\n\t\tuint[4] memory input;\n\t\tinput[0] = p1.X;\n\t\tinput[1] = p1.Y;\n\t\tinput[2] = p2.X;\n\t\tinput[3] = p2.Y;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return r the product of a point on G1 and a scalar, i.e.\n\t/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n\tfunction mul(G1Point memory p, uint s) internal returns (G1Point memory r) {\n\t\tuint[3] memory input;\n\t\tinput[0] = p.X;\n\t\tinput[1] = p.Y;\n\t\tinput[2] = s;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return the result of computing the pairing check\n\t/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n\t/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n\t/// return true.\n\tfunction pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {\n\t\trequire(p1.length == p2.length);\n\t\tuint elements = p1.length;\n\t\tuint inputSize = p1.length * 6;\n\t\tuint[] memory input = new uint[](inputSize);\n\t\tfor (uint i = 0; i < elements; i++)\n\t\t{\n\t\t\tinput[i * 6 + 0] = p1[i].X;\n\t\t\tinput[i * 6 + 1] = p1[i].Y;\n\t\t\tinput[i * 6 + 2] = p2[i].X[0];\n\t\t\tinput[i * 6 + 3] = p2[i].X[1];\n\t\t\tinput[i * 6 + 4] = p2[i].Y[0];\n\t\t\tinput[i * 6 + 5] = p2[i].Y[1];\n\t\t}\n\t\tuint[1] memory out;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t\treturn out[0] != 0;\n\t}\n\tfunction pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](2);\n\t\tG2Point[] memory p2 = new G2Point[](2);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd3(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](3);\n\t\tG2Point[] memory p2 = new G2Point[](3);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd4(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2,\n\t\t\tG1Point memory d1, G2Point memory d2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](4);\n\t\tG2Point[] memory p2 = new G2Point[](4);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp1[3] = d1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\tp2[3] = d2;\n\t\treturn pairing(p1, p2);\n\t}\n}\n\ncontract Test {\n\tusing Pairing for *;\n\tstruct VerifyingKey {\n\t\tPairing.G2Point A;\n\t\tPairing.G1Point B;\n\t\tPairing.G2Point C;\n\t\tPairing.G2Point gamma;\n\t\tPairing.G1Point gammaBeta1;\n\t\tPairing.G2Point gammaBeta2;\n\t\tPairing.G2Point Z;\n\t\tPairing.G1Point[] IC;\n\t}\n\tstruct Proof {\n\t\tPairing.G1Point A;\n\t\tPairing.G1Point A_p;\n\t\tPairing.G2Point B;\n\t\tPairing.G1Point B_p;\n\t\tPairing.G1Point C;\n\t\tPairing.G1Point C_p;\n\t\tPairing.G1Point K;\n\t\tPairing.G1Point H;\n\t}\n\tfunction f() public returns (bool) {\n\t\tPairing.G1Point memory p1;\n\t\tPairing.G1Point memory p2;\n\t\tp1.X = 1; p1.Y = 2;\n\t\tp2.X = 1; p2.Y = 2;\n\t\tPairing.G1Point memory explicit_sum = Pairing.add(p1, p2);\n\t\tPairing.G1Point memory scalar_prod = Pairing.mul(p1, 2);\n\t\treturn (explicit_sum.X == scalar_prod.X &&\n\t\t\texplicit_sum.Y == scalar_prod.Y);\n\t}\n\tfunction g() public returns (bool) {\n\t\tPairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));\n\t\t// should be zero\n\t\treturn (x.X == 0 && x.Y == 0);\n\t}\n\tfunction testMul() public returns (bool) {\n\t\tPairing.G1Point memory p;\n\t\t// @TODO The points here are reported to be not well-formed\n\t\tp.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;\n\t\tp.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;\n\t\tp = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);\n\t\treturn\n\t\t\tp.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&\n\t\t\tp.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;\n\t}\n\tfunction pair() public returns (bool) {\n\t\tPairing.G2Point memory fiveTimesP2 = Pairing.G2Point(\n\t\t\t[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],\n\t\t\t[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]\n\t\t);\n\t\t// The prime p in the base field F_p for G1\n\t\tuint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tPairing.G1Point[] memory g1points = new Pairing.G1Point[](2);\n\t\tPairing.G2Point[] memory g2points = new Pairing.G2Point[](2);\n\t\t// check e(5 P1, P2)e(-P1, 5 P2) == 1\n\t\tg1points[0] = Pairing.P1().mul(5);\n\t\tg1points[1] = Pairing.P1().negate();\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = fiveTimesP2;\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\t// check e(P1, P2)e(-P1, P2) == 1\n\t\tg1points[0] = Pairing.P1();\n\t\tg1points[1] = Pairing.P1();\n\t\tg1points[1].Y = p - g1points[1].Y;\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = Pairing.P2();\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tfunction verifyingKey() internal returns (VerifyingKey memory vk) {\n\t\tvk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);\n\t\tvk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);\n\t\tvk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);\n\t\tvk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);\n\t\tvk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);\n\t\tvk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);\n\t\tvk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);\n\t\tvk.IC = new Pairing.G1Point[](10);\n\t\tvk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);\n\t\tvk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);\n\t\tvk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);\n\t\tvk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);\n\t\tvk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);\n\t\tvk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);\n\t\tvk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);\n\t\tvk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);\n\t\tvk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);\n\t\tvk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);\n\t}\n\tfunction verify(uint[] memory input, Proof memory proof) internal returns (uint) {\n\t\tVerifyingKey memory vk = verifyingKey();\n\t\trequire(input.length + 1 == vk.IC.length);\n\t\t// Compute the linear combination vk_x\n\t\tPairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\t\tfor (uint i = 0; i < input.length; i++)\n\t\t\tvk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));\n\t\tvk_x = Pairing.add(vk_x, vk.IC[0]);\n\t\tif (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;\n\t\tif (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;\n\t\tif (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tproof.K, vk.gamma,\n\t\t\tPairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,\n\t\t\tPairing.negate(vk.gammaBeta1), proof.B\n\t\t)) return 4;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tPairing.add(vk_x, proof.A), proof.B,\n\t\t\tPairing.negate(proof.H), vk.Z,\n\t\t\tPairing.negate(proof.C), Pairing.P2()\n\t\t)) return 5;\n\t\treturn 0;\n\t}\n\tevent Verified(string);\n\tfunction verifyTx() public returns (bool) {\n\t\tuint[] memory input = new uint[](9);\n\t\tProof memory proof;\n\t\tproof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);\n\t\tproof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);\n\t\tproof.B = Pairing.G2Point(\n\t\t\t[8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],\n\t\t\t[15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);\n\t\tproof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);\n\t\tproof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);\n\t\tproof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);\n\t\tproof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);\n\t\tproof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);\n\t\tinput[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;\n\t\tinput[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;\n\t\tinput[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;\n\t\tinput[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;\n\t\tinput[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;\n\t\tinput[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;\n\t\tinput[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;\n\t\tinput[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;\n\t\tinput[8] = 18066496933330839731877828156604;\n\t\tif (verify(input, proof) == 0) {\n\t\t\temit Verified(\"Successfully verified.\");\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n/// Disabled because the point seems to be not well-formed, we need to find another example.\n/// testMul() -> true\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// library: Pairing\n// f() -> true\n// g() -> true\n// pair() -> true\n// gas irOptimized: 270409\n// gas legacy: 275219\n// gas legacyOptimized: 266862\n// verifyTx() -> true\n// ~ emit Verified(string): 0x20, 0x16, \"Successfully verified.\"\n// gas irOptimized: 785720\n// gas legacy: 801903\n// gas legacyOptimized: 770941\n" + }, + "prbmath_signed.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function div(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.div(y);\n }\n function exp(int256 x) external pure returns (int256 ret) {\n ret = x.exp();\n }\n function exp2(int256 x) external pure returns (int256 ret) {\n ret = x.exp2();\n }\n function gm(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.gm(y);\n }\n function log10(int256 x) external pure returns (int256 ret) {\n ret = x.log10();\n }\n function log2(int256 x) external pure returns (int256 ret) {\n ret = x.log2();\n }\n function mul(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.mul(y);\n }\n function pow(int256 x, uint256 y) external pure returns (int256 ret) {\n ret = x.pow(y);\n }\n function sqrt(int256 x) external pure returns (int256 ret) {\n ret = x.sqrt();\n }\n function benchmark(int256 x) external pure returns (int256 ret, int256 z1, int256 z2) {\n int256 y = x.mul(3).ceil();\n int256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 177903\n// gas irOptimized code: 1674400\n// gas legacy: 209723\n// gas legacy code: 2205000\n// gas legacyOptimized: 178012\n// gas legacyOptimized code: 1669600\n// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22137\n// gas legacy: 22767\n// gas legacyOptimized: 22282\n// exp(int256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24545\n// gas legacy: 25203\n// gas legacyOptimized: 24357\n// exp2(int256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24257\n// gas legacy: 24864\n// gas legacyOptimized: 24110\n// gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22970\n// gas legacy: 23228\n// gas legacyOptimized: 22683\n// log10(int256): 3141592653589793238 -> 4971498726941338506\n// gas irOptimized: 30609\n// gas legacy: 32934\n// gas legacyOptimized: 30323\n// log2(int256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28819\n// gas legacy: 31067\n// gas legacyOptimized: 28426\n// mul(int256,int256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22225\n// gas legacy: 22807\n// gas legacyOptimized: 22295\n// pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22635\n// gas legacy: 23508\n// gas legacyOptimized: 22921\n// sqrt(int256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22650\n// gas legacy: 22802\n// gas legacyOptimized: 22422\n// benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 36630\n// gas legacy: 36673\n// gas legacyOptimized: 34729\n" + }, + "prbmath_unsigned.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathUD60x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathUD60x18.sol\";\n\ncontract test {\n using PRBMathUD60x18 for uint256;\n\n function div(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.div(y);\n }\n function exp(uint256 x) external pure returns (uint256 ret) {\n ret = x.exp();\n }\n function exp2(uint256 x) external pure returns (uint256 ret) {\n ret = x.exp2();\n }\n function gm(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.gm(y);\n }\n function log10(uint256 x) external pure returns (uint256 ret) {\n ret = x.log10();\n }\n function log2(uint256 x) external pure returns (uint256 ret) {\n ret = x.log2();\n }\n function mul(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.mul(y);\n }\n function pow(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.pow(y);\n }\n function sqrt(uint256 x) external pure returns (uint256 ret) {\n ret = x.sqrt();\n }\n function benchmark(uint256 x) external pure returns (uint256 ret, uint256 z1, uint256 z2) {\n uint256 y = x.mul(3).ceil();\n uint256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 170626\n// gas irOptimized code: 1577400\n// gas legacy: 195206\n// gas legacy code: 1999000\n// gas legacyOptimized: 168857\n// gas legacyOptimized code: 1556200\n// div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22004\n// gas legacy: 22497\n// gas legacyOptimized: 22010\n// exp(uint256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24444\n// gas legacy: 25104\n// gas legacyOptimized: 24258\n// exp2(uint256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24198\n// gas legacy: 24814\n// gas legacyOptimized: 24062\n// gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22950\n// gas legacy: 23269\n// gas legacyOptimized: 22724\n// log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a\n// gas irOptimized: 30269\n// gas legacy: 32898\n// gas legacyOptimized: 29925\n// log2(uint256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28235\n// gas legacy: 30986\n// gas legacyOptimized: 28001\n// mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22048\n// gas legacy: 22604\n// gas legacyOptimized: 22090\n// pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22406\n// gas legacy: 23245\n// gas legacyOptimized: 22646\n// sqrt(uint256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22672\n// gas legacy: 22820\n// gas legacyOptimized: 22440\n// benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 35603\n// gas legacy: 35385\n// gas legacyOptimized: 33449\n" + }, + "strings.sol": { + "content": "==== ExternalSource: _stringutils/stringutils.sol ====\n==== Source: strings.sol ====\npragma abicoder v2;\nimport \"_stringutils/stringutils.sol\";\n\ncontract test {\n using strings for bytes32;\n using strings for string;\n using strings for strings.slice;\n\n function toSlice(string memory a) external pure returns (strings.slice memory) {\n return a.toSlice();\n }\n\n function roundtrip(string memory a) external pure returns (string memory) {\n return a.toSlice().toString();\n }\n\n function utf8len(string memory a) external pure returns (uint) {\n return a.toSlice().len();\n }\n\n function multiconcat(string memory a, uint count) public pure returns (string memory) {\n strings.slice memory s = a.toSlice();\n for (uint i = 0; i < count; i++) {\n s = s.concat(s).toSlice();\n }\n return s.toString();\n }\n\n function benchmark(string memory text, bytes32 seed) external pure returns (uint) {\n // Grow text.\n text = multiconcat(text, 10);\n\n strings.slice memory a = text.toSlice();\n strings.slice memory b = seed.toSliceB32();\n\n // Some heavy computation.\n bool c = b.equals(a) || b.startsWith(a);\n\n // Join as a list.\n strings.slice memory delim = c ? string(\",\").toSlice() : string(\";\").toSlice();\n strings.slice[] memory parts = new strings.slice[](2);\n parts[0] = a;\n parts[1] = b;\n string memory d = delim.join(parts);\n return d.toSlice().len();\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 95303\n// gas irOptimized code: 520000\n// gas legacy: 126346\n// gas legacy code: 932600\n// gas legacyOptimized: 102639\n// gas legacyOptimized code: 612400\n// toSlice(string): 0x20, 11, \"hello world\" -> 11, 0xa0\n// gas irOptimized: 22660\n// gas legacy: 23190\n// gas legacyOptimized: 22508\n// roundtrip(string): 0x20, 11, \"hello world\" -> 0x20, 11, \"hello world\"\n// gas irOptimized: 23408\n// gas legacy: 23820\n// gas legacyOptimized: 23123\n// utf8len(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 4 # Input: \"\ud83d\ude03\ud83d\ude03\ud83d\ude03\ud83d\ude03\" #\n// gas irOptimized: 24026\n// gas legacy: 25716\n// gas legacyOptimized: 24115\n// multiconcat(string,uint256): 0x40, 3, 11, \"hello world\" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times #\n// gas irOptimized: 28440\n// gas legacy: 31621\n// gas legacyOptimized: 27914\n// benchmark(string,bytes32): 0x40, 0x0842021, 8, \"solidity\" -> 0x2020\n// gas irOptimized: 1976778\n// gas legacy: 4234020\n// gas legacyOptimized: 2318668\n" + }, + "base64.sol": { + "content": "==== ExternalSource: _base64/base64_inline_asm.sol ====\n==== ExternalSource: _base64/base64_no_inline_asm.sol ====\n==== Source: base64.sol ====\n\nimport \"_base64/base64_inline_asm.sol\";\nimport \"_base64/base64_no_inline_asm.sol\";\n\ncontract test {\n function encode_inline_asm(bytes memory data) external pure returns (string memory) {\n return InlineAsmBase64.encode(data);\n }\n\n function encode_no_asm(bytes memory data) external pure returns (string memory) {\n return NoAsmBase64.encode(data);\n }\n\n function encode_inline_asm_large() external {\n for (uint i = 0; i < 1000; i++) {\n InlineAsmBase64.encode(\"foo\");\n }\n }\n\n function encode_no_asm_large() external {\n for (uint i = 0; i < 1000; i++) {\n NoAsmBase64.encode(\"foo\");\n }\n }\n}\n// Test cases derived from Base64 specification: RFC4648\n// https://datatracker.ietf.org/doc/html/rfc4648#section-10\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor()\n// gas irOptimized: 79076\n// gas irOptimized code: 322000\n// gas legacy: 102214\n// gas legacy code: 629800\n// gas legacyOptimized: 87926\n// gas legacyOptimized code: 429800\n// encode_inline_asm(bytes): 0x20, 0 -> 0x20, 0\n// encode_inline_asm(bytes): 0x20, 1, \"f\" -> 0x20, 4, \"Zg==\"\n// encode_inline_asm(bytes): 0x20, 2, \"fo\" -> 0x20, 4, \"Zm8=\"\n// encode_inline_asm(bytes): 0x20, 3, \"foo\" -> 0x20, 4, \"Zm9v\"\n// encode_inline_asm(bytes): 0x20, 4, \"foob\" -> 0x20, 8, \"Zm9vYg==\"\n// encode_inline_asm(bytes): 0x20, 5, \"fooba\" -> 0x20, 8, \"Zm9vYmE=\"\n// encode_inline_asm(bytes): 0x20, 6, \"foobar\" -> 0x20, 8, \"Zm9vYmFy\"\n// encode_no_asm(bytes): 0x20, 0 -> 0x20, 0\n// encode_no_asm(bytes): 0x20, 1, \"f\" -> 0x20, 4, \"Zg==\"\n// encode_no_asm(bytes): 0x20, 2, \"fo\" -> 0x20, 4, \"Zm8=\"\n// encode_no_asm(bytes): 0x20, 3, \"foo\" -> 0x20, 4, \"Zm9v\"\n// encode_no_asm(bytes): 0x20, 4, \"foob\" -> 0x20, 8, \"Zm9vYg==\"\n// encode_no_asm(bytes): 0x20, 5, \"fooba\" -> 0x20, 8, \"Zm9vYmE=\"\n// encode_no_asm(bytes): 0x20, 6, \"foobar\" -> 0x20, 8, \"Zm9vYmFy\"\n// encode_inline_asm_large()\n// gas irOptimized: 1406025\n// gas legacy: 1554038\n// gas legacyOptimized: 1132031\n// encode_no_asm_large()\n// gas irOptimized: 3512081\n// gas legacy: 4600082\n// gas legacyOptimized: 2813075\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract.sol b/examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract.sol new file mode 100644 index 00000000..c53e49f1 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract.sol @@ -0,0 +1,213 @@ +// ┏━━━┓━┏┓━┏┓━━┏━━━┓━━┏━━━┓━━━━┏━━━┓━━━━━━━━━━━━━━━━━━━┏┓━━━━━┏━━━┓━━━━━━━━━┏┓━━━━━━━━━━━━━━┏┓━ +// ┃┏━━┛┏┛┗┓┃┃━━┃┏━┓┃━━┃┏━┓┃━━━━┗┓┏┓┃━━━━━━━━━━━━━━━━━━┏┛┗┓━━━━┃┏━┓┃━━━━━━━━┏┛┗┓━━━━━━━━━━━━┏┛┗┓ +// ┃┗━━┓┗┓┏┛┃┗━┓┗┛┏┛┃━━┃┃━┃┃━━━━━┃┃┃┃┏━━┓┏━━┓┏━━┓┏━━┓┏┓┗┓┏┛━━━━┃┃━┗┛┏━━┓┏━┓━┗┓┏┛┏━┓┏━━┓━┏━━┓┗┓┏┛ +// ┃┏━━┛━┃┃━┃┏┓┃┏━┛┏┛━━┃┃━┃┃━━━━━┃┃┃┃┃┏┓┃┃┏┓┃┃┏┓┃┃━━┫┣┫━┃┃━━━━━┃┃━┏┓┃┏┓┃┃┏┓┓━┃┃━┃┏┛┗━┓┃━┃┏━┛━┃┃━ +// ┃┗━━┓━┃┗┓┃┃┃┃┃┃┗━┓┏┓┃┗━┛┃━━━━┏┛┗┛┃┃┃━┫┃┗┛┃┃┗┛┃┣━━┃┃┃━┃┗┓━━━━┃┗━┛┃┃┗┛┃┃┃┃┃━┃┗┓┃┃━┃┗┛┗┓┃┗━┓━┃┗┓ +// ┗━━━┛━┗━┛┗┛┗┛┗━━━┛┗┛┗━━━┛━━━━┗━━━┛┗━━┛┃┏━┛┗━━┛┗━━┛┗┛━┗━┛━━━━┗━━━┛┗━━┛┗┛┗┛━┗━┛┗┛━┗━━━┛┗━━┛━┗━┛ +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┃┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┗┛━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +// SPDX-License-Identifier: CC0-1.0 + +// This interface is designed to be compatible with the Vyper version. +/// @notice This is the Ethereum 2.0 deposit contract interface. +/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs +interface IDepositContract { + /// @notice A processed deposit event. + event DepositEvent( + bytes pubkey, + bytes withdrawal_credentials, + bytes amount, + bytes signature, + bytes index + ); + + /// @notice Submit a Phase 0 DepositData object. + /// @param pubkey A BLS12-381 public key. + /// @param withdrawal_credentials Commitment to a public key for withdrawals. + /// @param signature A BLS12-381 signature. + /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object. + /// Used as a protection against malformed input. + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) external payable; + + /// @notice Query the current deposit root hash. + /// @return The deposit root hash. + function get_deposit_root() external view returns (bytes32); + + /// @notice Query the current deposit count. + /// @return The deposit count encoded as a little endian 64-bit number. + function get_deposit_count() external view returns (bytes memory); +} + +// Based on official specification in https://eips.ethereum.org/EIPS/eip-165 +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceId The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceId` and + /// `interfaceId` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceId) external pure returns (bool); +} + +// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity. +// It tries to stay as close as possible to the original source code. +/// @notice This is the Ethereum 2.0 deposit contract interface. +/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs +contract DepositContract is IDepositContract, ERC165 { + uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32; + // NOTE: this also ensures `deposit_count` will fit into 64-bits + uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1; + + bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch; + uint256 deposit_count; + + bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes; + + constructor() public { + // Compute hashes in empty sparse Merkle tree + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) + zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height])); + } + + function get_deposit_root() override external view returns (bytes32) { + bytes32 node; + uint size = deposit_count; + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) { + if ((size & 1) == 1) + node = sha256(abi.encodePacked(branch[height], node)); + else + node = sha256(abi.encodePacked(node, zero_hashes[height])); + size /= 2; + } + return sha256(abi.encodePacked( + node, + to_little_endian_64(uint64(deposit_count)), + bytes24(0) + )); + } + + function get_deposit_count() override external view returns (bytes memory) { + return to_little_endian_64(uint64(deposit_count)); + } + + function deposit( + bytes calldata pubkey, + bytes calldata withdrawal_credentials, + bytes calldata signature, + bytes32 deposit_data_root + ) override external payable { + // Extended ABI length checks since dynamic types are used. + require(pubkey.length == 48, "DepositContract: invalid pubkey length"); + require(withdrawal_credentials.length == 32, "DepositContract: invalid withdrawal_credentials length"); + require(signature.length == 96, "DepositContract: invalid signature length"); + + // Check deposit amount + require(msg.value >= 1 ether, "DepositContract: deposit value too low"); + require(msg.value % 1 gwei == 0, "DepositContract: deposit value not multiple of gwei"); + uint deposit_amount = msg.value / 1 gwei; + require(deposit_amount <= type(uint64).max, "DepositContract: deposit value too high"); + + // Emit `DepositEvent` log + bytes memory amount = to_little_endian_64(uint64(deposit_amount)); + emit DepositEvent( + pubkey, + withdrawal_credentials, + amount, + signature, + to_little_endian_64(uint64(deposit_count)) + ); + + // Compute deposit data root (`DepositData` hash tree root) + bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0))); + bytes32 signature_root = sha256(abi.encodePacked( + sha256(abi.encodePacked(signature[:64])), + sha256(abi.encodePacked(signature[64:], bytes32(0))) + )); + bytes32 node = sha256(abi.encodePacked( + sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)), + sha256(abi.encodePacked(amount, bytes24(0), signature_root)) + )); + + // Verify computed and expected deposit data roots match + require(node == deposit_data_root, "DepositContract: reconstructed DepositData does not match supplied deposit_data_root"); + + // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`) + require(deposit_count < MAX_DEPOSIT_COUNT, "DepositContract: merkle tree full"); + + // Add deposit data root to Merkle tree (update a single `branch` node) + deposit_count += 1; + uint size = deposit_count; + for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) { + if ((size & 1) == 1) { + branch[height] = node; + return; + } + node = sha256(abi.encodePacked(branch[height], node)); + size /= 2; + } + // As the loop should always end prematurely with the `return` statement, + // this code should be unreachable. We assert `false` just to be safe. + assert(false); + } + + function supportsInterface(bytes4 interfaceId) override external pure returns (bool) { + return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId; + } + + function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) { + ret = new bytes(8); + bytes8 bytesValue = bytes8(value); + // Byteswapping during copying to bytes. + ret[0] = bytesValue[7]; + ret[1] = bytesValue[6]; + ret[2] = bytesValue[5]; + ret[3] = bytesValue[4]; + ret[4] = bytesValue[3]; + ret[5] = bytesValue[2]; + ret[6] = bytesValue[1]; + ret[7] = bytesValue[0]; + } +} +// ---- +// constructor() +// gas irOptimized: 809570 +// gas irOptimized code: 558000 +// gas legacy: 920228 +// gas legacy code: 1438800 +// gas legacyOptimized: 848699 +// gas legacyOptimized code: 878200 +// supportsInterface(bytes4): 0x0 -> 0 +// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # +// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # +// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # +// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e +// gas irOptimized: 109178 +// gas legacy: 142741 +// gas legacyOptimized: 117558 +// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit # +// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input # +// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e +// gas irOptimized: 109178 +// gas legacy: 142741 +// gas legacyOptimized: 117558 +// get_deposit_count() -> 0x20, 8, 0 +// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 # +// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00 +// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438 +// gas irOptimized: 109174 +// gas legacy: 142750 +// gas legacyOptimized: 117570 +// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000 +// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac # +// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000 +// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee +// gas irOptimized: 109174 +// gas legacy: 142750 +// gas legacyOptimized: 117570 +// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract_standard_input.json b/examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract_standard_input.json new file mode 100644 index 00000000..ae77c1f3 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_deposit_contract/deposit_contract_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + }, + "deposit_contract.sol": { + "content": "// \u250f\u2501\u2501\u2501\u2513\u2501\u250f\u2513\u2501\u250f\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\n// \u2503\u250f\u2501\u2501\u251b\u250f\u251b\u2517\u2513\u2503\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2517\u2513\u250f\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\n// \u2503\u2517\u2501\u2501\u2513\u2517\u2513\u250f\u251b\u2503\u2517\u2501\u2513\u2517\u251b\u250f\u251b\u2503\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2513\u2517\u2513\u250f\u251b\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2517\u251b\u250f\u2501\u2501\u2513\u250f\u2501\u2513\u2501\u2517\u2513\u250f\u251b\u250f\u2501\u2513\u250f\u2501\u2501\u2513\u2501\u250f\u2501\u2501\u2513\u2517\u2513\u250f\u251b\n// \u2503\u250f\u2501\u2501\u251b\u2501\u2503\u2503\u2501\u2503\u250f\u2513\u2503\u250f\u2501\u251b\u250f\u251b\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u2501\u2501\u252b\u2523\u252b\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u250f\u2513\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2513\u2501\u2503\u2503\u2501\u2503\u250f\u251b\u2517\u2501\u2513\u2503\u2501\u2503\u250f\u2501\u251b\u2501\u2503\u2503\u2501\n// \u2503\u2517\u2501\u2501\u2513\u2501\u2503\u2517\u2513\u2503\u2503\u2503\u2503\u2503\u2503\u2517\u2501\u2513\u250f\u2513\u2503\u2517\u2501\u251b\u2503\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u251b\u2503\u2503\u2503\u2501\u252b\u2503\u2517\u251b\u2503\u2503\u2517\u251b\u2503\u2523\u2501\u2501\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u2517\u2501\u251b\u2503\u2503\u2517\u251b\u2503\u2503\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2503\u2503\u2501\u2503\u2517\u251b\u2517\u2513\u2503\u2517\u2501\u2513\u2501\u2503\u2517\u2513\n// \u2517\u2501\u2501\u2501\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2503\u250f\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2501\u2517\u2501\u251b\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2517\u251b\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n /// @notice A processed deposit event.\n event DepositEvent(\n bytes pubkey,\n bytes withdrawal_credentials,\n bytes amount,\n bytes signature,\n bytes index\n );\n\n /// @notice Submit a Phase 0 DepositData object.\n /// @param pubkey A BLS12-381 public key.\n /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n /// @param signature A BLS12-381 signature.\n /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n /// Used as a protection against malformed input.\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) external payable;\n\n /// @notice Query the current deposit root hash.\n /// @return The deposit root hash.\n function get_deposit_root() external view returns (bytes32);\n\n /// @notice Query the current deposit count.\n /// @return The deposit count encoded as a little endian 64-bit number.\n function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceId` and\n /// `interfaceId` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n // NOTE: this also ensures `deposit_count` will fit into 64-bits\n uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n uint256 deposit_count;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n constructor() public {\n // Compute hashes in empty sparse Merkle tree\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n }\n\n function get_deposit_root() override external view returns (bytes32) {\n bytes32 node;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1)\n node = sha256(abi.encodePacked(branch[height], node));\n else\n node = sha256(abi.encodePacked(node, zero_hashes[height]));\n size /= 2;\n }\n return sha256(abi.encodePacked(\n node,\n to_little_endian_64(uint64(deposit_count)),\n bytes24(0)\n ));\n }\n\n function get_deposit_count() override external view returns (bytes memory) {\n return to_little_endian_64(uint64(deposit_count));\n }\n\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) override external payable {\n // Extended ABI length checks since dynamic types are used.\n require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n // Check deposit amount\n require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n uint deposit_amount = msg.value / 1 gwei;\n require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n // Emit `DepositEvent` log\n bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n emit DepositEvent(\n pubkey,\n withdrawal_credentials,\n amount,\n signature,\n to_little_endian_64(uint64(deposit_count))\n );\n\n // Compute deposit data root (`DepositData` hash tree root)\n bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n bytes32 signature_root = sha256(abi.encodePacked(\n sha256(abi.encodePacked(signature[:64])),\n sha256(abi.encodePacked(signature[64:], bytes32(0)))\n ));\n bytes32 node = sha256(abi.encodePacked(\n sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n ));\n\n // Verify computed and expected deposit data roots match\n require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n // Add deposit data root to Merkle tree (update a single `branch` node)\n deposit_count += 1;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1) {\n branch[height] = node;\n return;\n }\n node = sha256(abi.encodePacked(branch[height], node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n }\n\n function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed.sol b/examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed.sol new file mode 100644 index 00000000..cb345757 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed.sol @@ -0,0 +1,96 @@ +==== ExternalSource: _prbmath/PRBMathCommon.sol ==== +==== ExternalSource: _prbmath/PRBMathSD59x18.sol ==== +==== Source: prbmath.sol ==== +import "_prbmath/PRBMathSD59x18.sol"; + +contract test { + using PRBMathSD59x18 for int256; + + function div(int256 x, int256 y) external pure returns (int256 ret) { + ret = x.div(y); + } + function exp(int256 x) external pure returns (int256 ret) { + ret = x.exp(); + } + function exp2(int256 x) external pure returns (int256 ret) { + ret = x.exp2(); + } + function gm(int256 x, int256 y) external pure returns (int256 ret) { + ret = x.gm(y); + } + function log10(int256 x) external pure returns (int256 ret) { + ret = x.log10(); + } + function log2(int256 x) external pure returns (int256 ret) { + ret = x.log2(); + } + function mul(int256 x, int256 y) external pure returns (int256 ret) { + ret = x.mul(y); + } + function pow(int256 x, uint256 y) external pure returns (int256 ret) { + ret = x.pow(y); + } + function sqrt(int256 x) external pure returns (int256 ret) { + ret = x.sqrt(); + } + function benchmark(int256 x) external pure returns (int256 ret, int256 z1, int256 z2) { + int256 y = x.mul(3).ceil(); + int256 z = y.div(x); + for (uint i = 0; i < 10; i++) + z = z.sqrt(); + ret = z; + + // Check precision + z1 = z.ceil(); + z2 = z.sqrt().pow(2).ceil(); + assert(z1 == z2); + } +} +// ---- +// constructor() +// gas irOptimized: 177903 +// gas irOptimized code: 1674400 +// gas legacy: 209723 +// gas legacy code: 2205000 +// gas legacyOptimized: 178012 +// gas legacyOptimized code: 1669600 +// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 +// gas irOptimized: 22137 +// gas legacy: 22767 +// gas legacyOptimized: 22282 +// exp(int256): 3141592653589793238 -> 23140692632779268978 +// gas irOptimized: 24545 +// gas legacy: 25203 +// gas legacyOptimized: 24357 +// exp2(int256): 3141592653589793238 -> 8824977827076287620 +// gas irOptimized: 24257 +// gas legacy: 24864 +// gas legacyOptimized: 24110 +// gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601 +// gas irOptimized: 22970 +// gas legacy: 23228 +// gas legacyOptimized: 22683 +// log10(int256): 3141592653589793238 -> 4971498726941338506 +// gas irOptimized: 30609 +// gas legacy: 32934 +// gas legacyOptimized: 30323 +// log2(int256): 3141592653589793238 -> 1651496129472318782 +// gas irOptimized: 28819 +// gas legacy: 31067 +// gas legacyOptimized: 28426 +// mul(int256,int256): 3141592653589793238, 88714123 -> 278703637 +// gas irOptimized: 22225 +// gas legacy: 22807 +// gas legacyOptimized: 22295 +// pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040 +// gas irOptimized: 22635 +// gas legacy: 23508 +// gas legacyOptimized: 22921 +// sqrt(int256): 3141592653589793238 -> 1772453850905516027 +// gas irOptimized: 22650 +// gas legacy: 22802 +// gas legacyOptimized: 22422 +// benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 +// gas irOptimized: 36630 +// gas legacy: 36673 +// gas legacyOptimized: 34729 diff --git a/examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed_standard_input.json b/examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed_standard_input.json new file mode 100644 index 00000000..4018a872 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_prbmath_signed/prbmath_signed_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + }, + "deposit_contract.sol": { + "content": "// \u250f\u2501\u2501\u2501\u2513\u2501\u250f\u2513\u2501\u250f\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\n// \u2503\u250f\u2501\u2501\u251b\u250f\u251b\u2517\u2513\u2503\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2517\u2513\u250f\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\n// \u2503\u2517\u2501\u2501\u2513\u2517\u2513\u250f\u251b\u2503\u2517\u2501\u2513\u2517\u251b\u250f\u251b\u2503\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2513\u2517\u2513\u250f\u251b\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2517\u251b\u250f\u2501\u2501\u2513\u250f\u2501\u2513\u2501\u2517\u2513\u250f\u251b\u250f\u2501\u2513\u250f\u2501\u2501\u2513\u2501\u250f\u2501\u2501\u2513\u2517\u2513\u250f\u251b\n// \u2503\u250f\u2501\u2501\u251b\u2501\u2503\u2503\u2501\u2503\u250f\u2513\u2503\u250f\u2501\u251b\u250f\u251b\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u2501\u2501\u252b\u2523\u252b\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u250f\u2513\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2513\u2501\u2503\u2503\u2501\u2503\u250f\u251b\u2517\u2501\u2513\u2503\u2501\u2503\u250f\u2501\u251b\u2501\u2503\u2503\u2501\n// \u2503\u2517\u2501\u2501\u2513\u2501\u2503\u2517\u2513\u2503\u2503\u2503\u2503\u2503\u2503\u2517\u2501\u2513\u250f\u2513\u2503\u2517\u2501\u251b\u2503\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u251b\u2503\u2503\u2503\u2501\u252b\u2503\u2517\u251b\u2503\u2503\u2517\u251b\u2503\u2523\u2501\u2501\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u2517\u2501\u251b\u2503\u2503\u2517\u251b\u2503\u2503\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2503\u2503\u2501\u2503\u2517\u251b\u2517\u2513\u2503\u2517\u2501\u2513\u2501\u2503\u2517\u2513\n// \u2517\u2501\u2501\u2501\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2503\u250f\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2501\u2517\u2501\u251b\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2517\u251b\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n /// @notice A processed deposit event.\n event DepositEvent(\n bytes pubkey,\n bytes withdrawal_credentials,\n bytes amount,\n bytes signature,\n bytes index\n );\n\n /// @notice Submit a Phase 0 DepositData object.\n /// @param pubkey A BLS12-381 public key.\n /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n /// @param signature A BLS12-381 signature.\n /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n /// Used as a protection against malformed input.\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) external payable;\n\n /// @notice Query the current deposit root hash.\n /// @return The deposit root hash.\n function get_deposit_root() external view returns (bytes32);\n\n /// @notice Query the current deposit count.\n /// @return The deposit count encoded as a little endian 64-bit number.\n function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceId` and\n /// `interfaceId` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n // NOTE: this also ensures `deposit_count` will fit into 64-bits\n uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n uint256 deposit_count;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n constructor() public {\n // Compute hashes in empty sparse Merkle tree\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n }\n\n function get_deposit_root() override external view returns (bytes32) {\n bytes32 node;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1)\n node = sha256(abi.encodePacked(branch[height], node));\n else\n node = sha256(abi.encodePacked(node, zero_hashes[height]));\n size /= 2;\n }\n return sha256(abi.encodePacked(\n node,\n to_little_endian_64(uint64(deposit_count)),\n bytes24(0)\n ));\n }\n\n function get_deposit_count() override external view returns (bytes memory) {\n return to_little_endian_64(uint64(deposit_count));\n }\n\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) override external payable {\n // Extended ABI length checks since dynamic types are used.\n require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n // Check deposit amount\n require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n uint deposit_amount = msg.value / 1 gwei;\n require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n // Emit `DepositEvent` log\n bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n emit DepositEvent(\n pubkey,\n withdrawal_credentials,\n amount,\n signature,\n to_little_endian_64(uint64(deposit_count))\n );\n\n // Compute deposit data root (`DepositData` hash tree root)\n bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n bytes32 signature_root = sha256(abi.encodePacked(\n sha256(abi.encodePacked(signature[:64])),\n sha256(abi.encodePacked(signature[64:], bytes32(0)))\n ));\n bytes32 node = sha256(abi.encodePacked(\n sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n ));\n\n // Verify computed and expected deposit data roots match\n require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n // Add deposit data root to Merkle tree (update a single `branch` node)\n deposit_count += 1;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1) {\n branch[height] = node;\n return;\n }\n node = sha256(abi.encodePacked(branch[height], node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n }\n\n function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n" + }, + "snark.sol": { + "content": "library Pairing {\n\tstruct G1Point {\n\t\tuint X;\n\t\tuint Y;\n\t}\n\t// Encoding of field elements is: X[0] * z + X[1]\n\tstruct G2Point {\n\t\tuint[2] X;\n\t\tuint[2] Y;\n\t}\n\n\t/// @return the generator of G1\n\tfunction P1() internal returns (G1Point memory) {\n\t\treturn G1Point(1, 2);\n\t}\n\n\t/// @return the generator of G2\n\tfunction P2() internal returns (G2Point memory) {\n\t\treturn G2Point(\n\t\t\t[11559732032986387107991004021392285783925812861821192530917403151452391805634,\n\t\t\t 10857046999023057135944570762232829481370756359578518086990519993285655852781],\n\t\t\t[4082367875863433681332203403145435568316851327593401208105741076214120093531,\n\t\t\t 8495653923123431417604973247489272438418190587263600148770280649306958101930]\n\t\t);\n\t}\n\n\t/// @return the negation of p, i.e. p.add(p.negate()) should be zero.\n\tfunction negate(G1Point memory p) internal returns (G1Point memory) {\n\t\t// The prime q in the base field F_q for G1\n\t\tuint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tif (p.X == 0 && p.Y == 0)\n\t\t\treturn G1Point(0, 0);\n\t\treturn G1Point(p.X, q - (p.Y % q));\n\t}\n\n\t/// @return r the sum of two points of G1\n\tfunction add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {\n\t\tuint[4] memory input;\n\t\tinput[0] = p1.X;\n\t\tinput[1] = p1.Y;\n\t\tinput[2] = p2.X;\n\t\tinput[3] = p2.Y;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return r the product of a point on G1 and a scalar, i.e.\n\t/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n\tfunction mul(G1Point memory p, uint s) internal returns (G1Point memory r) {\n\t\tuint[3] memory input;\n\t\tinput[0] = p.X;\n\t\tinput[1] = p.Y;\n\t\tinput[2] = s;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return the result of computing the pairing check\n\t/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n\t/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n\t/// return true.\n\tfunction pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {\n\t\trequire(p1.length == p2.length);\n\t\tuint elements = p1.length;\n\t\tuint inputSize = p1.length * 6;\n\t\tuint[] memory input = new uint[](inputSize);\n\t\tfor (uint i = 0; i < elements; i++)\n\t\t{\n\t\t\tinput[i * 6 + 0] = p1[i].X;\n\t\t\tinput[i * 6 + 1] = p1[i].Y;\n\t\t\tinput[i * 6 + 2] = p2[i].X[0];\n\t\t\tinput[i * 6 + 3] = p2[i].X[1];\n\t\t\tinput[i * 6 + 4] = p2[i].Y[0];\n\t\t\tinput[i * 6 + 5] = p2[i].Y[1];\n\t\t}\n\t\tuint[1] memory out;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t\treturn out[0] != 0;\n\t}\n\tfunction pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](2);\n\t\tG2Point[] memory p2 = new G2Point[](2);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd3(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](3);\n\t\tG2Point[] memory p2 = new G2Point[](3);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd4(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2,\n\t\t\tG1Point memory d1, G2Point memory d2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](4);\n\t\tG2Point[] memory p2 = new G2Point[](4);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp1[3] = d1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\tp2[3] = d2;\n\t\treturn pairing(p1, p2);\n\t}\n}\n\ncontract Test {\n\tusing Pairing for *;\n\tstruct VerifyingKey {\n\t\tPairing.G2Point A;\n\t\tPairing.G1Point B;\n\t\tPairing.G2Point C;\n\t\tPairing.G2Point gamma;\n\t\tPairing.G1Point gammaBeta1;\n\t\tPairing.G2Point gammaBeta2;\n\t\tPairing.G2Point Z;\n\t\tPairing.G1Point[] IC;\n\t}\n\tstruct Proof {\n\t\tPairing.G1Point A;\n\t\tPairing.G1Point A_p;\n\t\tPairing.G2Point B;\n\t\tPairing.G1Point B_p;\n\t\tPairing.G1Point C;\n\t\tPairing.G1Point C_p;\n\t\tPairing.G1Point K;\n\t\tPairing.G1Point H;\n\t}\n\tfunction f() public returns (bool) {\n\t\tPairing.G1Point memory p1;\n\t\tPairing.G1Point memory p2;\n\t\tp1.X = 1; p1.Y = 2;\n\t\tp2.X = 1; p2.Y = 2;\n\t\tPairing.G1Point memory explicit_sum = Pairing.add(p1, p2);\n\t\tPairing.G1Point memory scalar_prod = Pairing.mul(p1, 2);\n\t\treturn (explicit_sum.X == scalar_prod.X &&\n\t\t\texplicit_sum.Y == scalar_prod.Y);\n\t}\n\tfunction g() public returns (bool) {\n\t\tPairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));\n\t\t// should be zero\n\t\treturn (x.X == 0 && x.Y == 0);\n\t}\n\tfunction testMul() public returns (bool) {\n\t\tPairing.G1Point memory p;\n\t\t// @TODO The points here are reported to be not well-formed\n\t\tp.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;\n\t\tp.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;\n\t\tp = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);\n\t\treturn\n\t\t\tp.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&\n\t\t\tp.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;\n\t}\n\tfunction pair() public returns (bool) {\n\t\tPairing.G2Point memory fiveTimesP2 = Pairing.G2Point(\n\t\t\t[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],\n\t\t\t[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]\n\t\t);\n\t\t// The prime p in the base field F_p for G1\n\t\tuint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tPairing.G1Point[] memory g1points = new Pairing.G1Point[](2);\n\t\tPairing.G2Point[] memory g2points = new Pairing.G2Point[](2);\n\t\t// check e(5 P1, P2)e(-P1, 5 P2) == 1\n\t\tg1points[0] = Pairing.P1().mul(5);\n\t\tg1points[1] = Pairing.P1().negate();\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = fiveTimesP2;\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\t// check e(P1, P2)e(-P1, P2) == 1\n\t\tg1points[0] = Pairing.P1();\n\t\tg1points[1] = Pairing.P1();\n\t\tg1points[1].Y = p - g1points[1].Y;\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = Pairing.P2();\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tfunction verifyingKey() internal returns (VerifyingKey memory vk) {\n\t\tvk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);\n\t\tvk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);\n\t\tvk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);\n\t\tvk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);\n\t\tvk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);\n\t\tvk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);\n\t\tvk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);\n\t\tvk.IC = new Pairing.G1Point[](10);\n\t\tvk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);\n\t\tvk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);\n\t\tvk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);\n\t\tvk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);\n\t\tvk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);\n\t\tvk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);\n\t\tvk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);\n\t\tvk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);\n\t\tvk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);\n\t\tvk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);\n\t}\n\tfunction verify(uint[] memory input, Proof memory proof) internal returns (uint) {\n\t\tVerifyingKey memory vk = verifyingKey();\n\t\trequire(input.length + 1 == vk.IC.length);\n\t\t// Compute the linear combination vk_x\n\t\tPairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\t\tfor (uint i = 0; i < input.length; i++)\n\t\t\tvk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));\n\t\tvk_x = Pairing.add(vk_x, vk.IC[0]);\n\t\tif (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;\n\t\tif (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;\n\t\tif (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tproof.K, vk.gamma,\n\t\t\tPairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,\n\t\t\tPairing.negate(vk.gammaBeta1), proof.B\n\t\t)) return 4;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tPairing.add(vk_x, proof.A), proof.B,\n\t\t\tPairing.negate(proof.H), vk.Z,\n\t\t\tPairing.negate(proof.C), Pairing.P2()\n\t\t)) return 5;\n\t\treturn 0;\n\t}\n\tevent Verified(string);\n\tfunction verifyTx() public returns (bool) {\n\t\tuint[] memory input = new uint[](9);\n\t\tProof memory proof;\n\t\tproof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);\n\t\tproof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);\n\t\tproof.B = Pairing.G2Point(\n\t\t\t[8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],\n\t\t\t[15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);\n\t\tproof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);\n\t\tproof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);\n\t\tproof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);\n\t\tproof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);\n\t\tproof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);\n\t\tinput[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;\n\t\tinput[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;\n\t\tinput[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;\n\t\tinput[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;\n\t\tinput[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;\n\t\tinput[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;\n\t\tinput[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;\n\t\tinput[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;\n\t\tinput[8] = 18066496933330839731877828156604;\n\t\tif (verify(input, proof) == 0) {\n\t\t\temit Verified(\"Successfully verified.\");\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n/// Disabled because the point seems to be not well-formed, we need to find another example.\n/// testMul() -> true\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// library: Pairing\n// f() -> true\n// g() -> true\n// pair() -> true\n// gas irOptimized: 270409\n// gas legacy: 275219\n// gas legacyOptimized: 266862\n// verifyTx() -> true\n// ~ emit Verified(string): 0x20, 0x16, \"Successfully verified.\"\n// gas irOptimized: 785720\n// gas legacy: 801903\n// gas legacyOptimized: 770941\n" + }, + "prbmath_signed.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function div(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.div(y);\n }\n function exp(int256 x) external pure returns (int256 ret) {\n ret = x.exp();\n }\n function exp2(int256 x) external pure returns (int256 ret) {\n ret = x.exp2();\n }\n function gm(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.gm(y);\n }\n function log10(int256 x) external pure returns (int256 ret) {\n ret = x.log10();\n }\n function log2(int256 x) external pure returns (int256 ret) {\n ret = x.log2();\n }\n function mul(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.mul(y);\n }\n function pow(int256 x, uint256 y) external pure returns (int256 ret) {\n ret = x.pow(y);\n }\n function sqrt(int256 x) external pure returns (int256 ret) {\n ret = x.sqrt();\n }\n function benchmark(int256 x) external pure returns (int256 ret, int256 z1, int256 z2) {\n int256 y = x.mul(3).ceil();\n int256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 177903\n// gas irOptimized code: 1674400\n// gas legacy: 209723\n// gas legacy code: 2205000\n// gas legacyOptimized: 178012\n// gas legacyOptimized code: 1669600\n// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22137\n// gas legacy: 22767\n// gas legacyOptimized: 22282\n// exp(int256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24545\n// gas legacy: 25203\n// gas legacyOptimized: 24357\n// exp2(int256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24257\n// gas legacy: 24864\n// gas legacyOptimized: 24110\n// gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22970\n// gas legacy: 23228\n// gas legacyOptimized: 22683\n// log10(int256): 3141592653589793238 -> 4971498726941338506\n// gas irOptimized: 30609\n// gas legacy: 32934\n// gas legacyOptimized: 30323\n// log2(int256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28819\n// gas legacy: 31067\n// gas legacyOptimized: 28426\n// mul(int256,int256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22225\n// gas legacy: 22807\n// gas legacyOptimized: 22295\n// pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22635\n// gas legacy: 23508\n// gas legacyOptimized: 22921\n// sqrt(int256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22650\n// gas legacy: 22802\n// gas legacyOptimized: 22422\n// benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 36630\n// gas legacy: 36673\n// gas legacyOptimized: 34729\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned.sol b/examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned.sol new file mode 100644 index 00000000..5902ba49 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned.sol @@ -0,0 +1,96 @@ +==== ExternalSource: _prbmath/PRBMathCommon.sol ==== +==== ExternalSource: _prbmath/PRBMathUD60x18.sol ==== +==== Source: prbmath.sol ==== +import "_prbmath/PRBMathUD60x18.sol"; + +contract test { + using PRBMathUD60x18 for uint256; + + function div(uint256 x, uint256 y) external pure returns (uint256 ret) { + ret = x.div(y); + } + function exp(uint256 x) external pure returns (uint256 ret) { + ret = x.exp(); + } + function exp2(uint256 x) external pure returns (uint256 ret) { + ret = x.exp2(); + } + function gm(uint256 x, uint256 y) external pure returns (uint256 ret) { + ret = x.gm(y); + } + function log10(uint256 x) external pure returns (uint256 ret) { + ret = x.log10(); + } + function log2(uint256 x) external pure returns (uint256 ret) { + ret = x.log2(); + } + function mul(uint256 x, uint256 y) external pure returns (uint256 ret) { + ret = x.mul(y); + } + function pow(uint256 x, uint256 y) external pure returns (uint256 ret) { + ret = x.pow(y); + } + function sqrt(uint256 x) external pure returns (uint256 ret) { + ret = x.sqrt(); + } + function benchmark(uint256 x) external pure returns (uint256 ret, uint256 z1, uint256 z2) { + uint256 y = x.mul(3).ceil(); + uint256 z = y.div(x); + for (uint i = 0; i < 10; i++) + z = z.sqrt(); + ret = z; + + // Check precision + z1 = z.ceil(); + z2 = z.sqrt().pow(2).ceil(); + assert(z1 == z2); + } +} +// ---- +// constructor() +// gas irOptimized: 170626 +// gas irOptimized code: 1577400 +// gas legacy: 195206 +// gas legacy code: 1999000 +// gas legacyOptimized: 168857 +// gas legacyOptimized code: 1556200 +// div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 +// gas irOptimized: 22004 +// gas legacy: 22497 +// gas legacyOptimized: 22010 +// exp(uint256): 3141592653589793238 -> 23140692632779268978 +// gas irOptimized: 24444 +// gas legacy: 25104 +// gas legacyOptimized: 24258 +// exp2(uint256): 3141592653589793238 -> 8824977827076287620 +// gas irOptimized: 24198 +// gas legacy: 24814 +// gas legacyOptimized: 24062 +// gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601 +// gas irOptimized: 22950 +// gas legacy: 23269 +// gas legacyOptimized: 22724 +// log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a +// gas irOptimized: 30269 +// gas legacy: 32898 +// gas legacyOptimized: 29925 +// log2(uint256): 3141592653589793238 -> 1651496129472318782 +// gas irOptimized: 28235 +// gas legacy: 30986 +// gas legacyOptimized: 28001 +// mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637 +// gas irOptimized: 22048 +// gas legacy: 22604 +// gas legacyOptimized: 22090 +// pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040 +// gas irOptimized: 22406 +// gas legacy: 23245 +// gas legacyOptimized: 22646 +// sqrt(uint256): 3141592653589793238 -> 1772453850905516027 +// gas irOptimized: 22672 +// gas legacy: 22820 +// gas legacyOptimized: 22440 +// benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 +// gas irOptimized: 35603 +// gas legacy: 35385 +// gas legacyOptimized: 33449 diff --git a/examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned_standard_input.json b/examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned_standard_input.json new file mode 100644 index 00000000..74419709 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_prbmath_unsigned/prbmath_unsigned_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + }, + "deposit_contract.sol": { + "content": "// \u250f\u2501\u2501\u2501\u2513\u2501\u250f\u2513\u2501\u250f\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\n// \u2503\u250f\u2501\u2501\u251b\u250f\u251b\u2517\u2513\u2503\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2517\u2513\u250f\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\n// \u2503\u2517\u2501\u2501\u2513\u2517\u2513\u250f\u251b\u2503\u2517\u2501\u2513\u2517\u251b\u250f\u251b\u2503\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2513\u2517\u2513\u250f\u251b\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2517\u251b\u250f\u2501\u2501\u2513\u250f\u2501\u2513\u2501\u2517\u2513\u250f\u251b\u250f\u2501\u2513\u250f\u2501\u2501\u2513\u2501\u250f\u2501\u2501\u2513\u2517\u2513\u250f\u251b\n// \u2503\u250f\u2501\u2501\u251b\u2501\u2503\u2503\u2501\u2503\u250f\u2513\u2503\u250f\u2501\u251b\u250f\u251b\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u2501\u2501\u252b\u2523\u252b\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u250f\u2513\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2513\u2501\u2503\u2503\u2501\u2503\u250f\u251b\u2517\u2501\u2513\u2503\u2501\u2503\u250f\u2501\u251b\u2501\u2503\u2503\u2501\n// \u2503\u2517\u2501\u2501\u2513\u2501\u2503\u2517\u2513\u2503\u2503\u2503\u2503\u2503\u2503\u2517\u2501\u2513\u250f\u2513\u2503\u2517\u2501\u251b\u2503\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u251b\u2503\u2503\u2503\u2501\u252b\u2503\u2517\u251b\u2503\u2503\u2517\u251b\u2503\u2523\u2501\u2501\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u2517\u2501\u251b\u2503\u2503\u2517\u251b\u2503\u2503\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2503\u2503\u2501\u2503\u2517\u251b\u2517\u2513\u2503\u2517\u2501\u2513\u2501\u2503\u2517\u2513\n// \u2517\u2501\u2501\u2501\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2503\u250f\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2501\u2517\u2501\u251b\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2517\u251b\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n /// @notice A processed deposit event.\n event DepositEvent(\n bytes pubkey,\n bytes withdrawal_credentials,\n bytes amount,\n bytes signature,\n bytes index\n );\n\n /// @notice Submit a Phase 0 DepositData object.\n /// @param pubkey A BLS12-381 public key.\n /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n /// @param signature A BLS12-381 signature.\n /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n /// Used as a protection against malformed input.\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) external payable;\n\n /// @notice Query the current deposit root hash.\n /// @return The deposit root hash.\n function get_deposit_root() external view returns (bytes32);\n\n /// @notice Query the current deposit count.\n /// @return The deposit count encoded as a little endian 64-bit number.\n function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceId` and\n /// `interfaceId` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n // NOTE: this also ensures `deposit_count` will fit into 64-bits\n uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n uint256 deposit_count;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n constructor() public {\n // Compute hashes in empty sparse Merkle tree\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n }\n\n function get_deposit_root() override external view returns (bytes32) {\n bytes32 node;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1)\n node = sha256(abi.encodePacked(branch[height], node));\n else\n node = sha256(abi.encodePacked(node, zero_hashes[height]));\n size /= 2;\n }\n return sha256(abi.encodePacked(\n node,\n to_little_endian_64(uint64(deposit_count)),\n bytes24(0)\n ));\n }\n\n function get_deposit_count() override external view returns (bytes memory) {\n return to_little_endian_64(uint64(deposit_count));\n }\n\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) override external payable {\n // Extended ABI length checks since dynamic types are used.\n require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n // Check deposit amount\n require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n uint deposit_amount = msg.value / 1 gwei;\n require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n // Emit `DepositEvent` log\n bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n emit DepositEvent(\n pubkey,\n withdrawal_credentials,\n amount,\n signature,\n to_little_endian_64(uint64(deposit_count))\n );\n\n // Compute deposit data root (`DepositData` hash tree root)\n bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n bytes32 signature_root = sha256(abi.encodePacked(\n sha256(abi.encodePacked(signature[:64])),\n sha256(abi.encodePacked(signature[64:], bytes32(0)))\n ));\n bytes32 node = sha256(abi.encodePacked(\n sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n ));\n\n // Verify computed and expected deposit data roots match\n require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n // Add deposit data root to Merkle tree (update a single `branch` node)\n deposit_count += 1;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1) {\n branch[height] = node;\n return;\n }\n node = sha256(abi.encodePacked(branch[height], node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n }\n\n function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n" + }, + "snark.sol": { + "content": "library Pairing {\n\tstruct G1Point {\n\t\tuint X;\n\t\tuint Y;\n\t}\n\t// Encoding of field elements is: X[0] * z + X[1]\n\tstruct G2Point {\n\t\tuint[2] X;\n\t\tuint[2] Y;\n\t}\n\n\t/// @return the generator of G1\n\tfunction P1() internal returns (G1Point memory) {\n\t\treturn G1Point(1, 2);\n\t}\n\n\t/// @return the generator of G2\n\tfunction P2() internal returns (G2Point memory) {\n\t\treturn G2Point(\n\t\t\t[11559732032986387107991004021392285783925812861821192530917403151452391805634,\n\t\t\t 10857046999023057135944570762232829481370756359578518086990519993285655852781],\n\t\t\t[4082367875863433681332203403145435568316851327593401208105741076214120093531,\n\t\t\t 8495653923123431417604973247489272438418190587263600148770280649306958101930]\n\t\t);\n\t}\n\n\t/// @return the negation of p, i.e. p.add(p.negate()) should be zero.\n\tfunction negate(G1Point memory p) internal returns (G1Point memory) {\n\t\t// The prime q in the base field F_q for G1\n\t\tuint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tif (p.X == 0 && p.Y == 0)\n\t\t\treturn G1Point(0, 0);\n\t\treturn G1Point(p.X, q - (p.Y % q));\n\t}\n\n\t/// @return r the sum of two points of G1\n\tfunction add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {\n\t\tuint[4] memory input;\n\t\tinput[0] = p1.X;\n\t\tinput[1] = p1.Y;\n\t\tinput[2] = p2.X;\n\t\tinput[3] = p2.Y;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return r the product of a point on G1 and a scalar, i.e.\n\t/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n\tfunction mul(G1Point memory p, uint s) internal returns (G1Point memory r) {\n\t\tuint[3] memory input;\n\t\tinput[0] = p.X;\n\t\tinput[1] = p.Y;\n\t\tinput[2] = s;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return the result of computing the pairing check\n\t/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n\t/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n\t/// return true.\n\tfunction pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {\n\t\trequire(p1.length == p2.length);\n\t\tuint elements = p1.length;\n\t\tuint inputSize = p1.length * 6;\n\t\tuint[] memory input = new uint[](inputSize);\n\t\tfor (uint i = 0; i < elements; i++)\n\t\t{\n\t\t\tinput[i * 6 + 0] = p1[i].X;\n\t\t\tinput[i * 6 + 1] = p1[i].Y;\n\t\t\tinput[i * 6 + 2] = p2[i].X[0];\n\t\t\tinput[i * 6 + 3] = p2[i].X[1];\n\t\t\tinput[i * 6 + 4] = p2[i].Y[0];\n\t\t\tinput[i * 6 + 5] = p2[i].Y[1];\n\t\t}\n\t\tuint[1] memory out;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t\treturn out[0] != 0;\n\t}\n\tfunction pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](2);\n\t\tG2Point[] memory p2 = new G2Point[](2);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd3(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](3);\n\t\tG2Point[] memory p2 = new G2Point[](3);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd4(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2,\n\t\t\tG1Point memory d1, G2Point memory d2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](4);\n\t\tG2Point[] memory p2 = new G2Point[](4);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp1[3] = d1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\tp2[3] = d2;\n\t\treturn pairing(p1, p2);\n\t}\n}\n\ncontract Test {\n\tusing Pairing for *;\n\tstruct VerifyingKey {\n\t\tPairing.G2Point A;\n\t\tPairing.G1Point B;\n\t\tPairing.G2Point C;\n\t\tPairing.G2Point gamma;\n\t\tPairing.G1Point gammaBeta1;\n\t\tPairing.G2Point gammaBeta2;\n\t\tPairing.G2Point Z;\n\t\tPairing.G1Point[] IC;\n\t}\n\tstruct Proof {\n\t\tPairing.G1Point A;\n\t\tPairing.G1Point A_p;\n\t\tPairing.G2Point B;\n\t\tPairing.G1Point B_p;\n\t\tPairing.G1Point C;\n\t\tPairing.G1Point C_p;\n\t\tPairing.G1Point K;\n\t\tPairing.G1Point H;\n\t}\n\tfunction f() public returns (bool) {\n\t\tPairing.G1Point memory p1;\n\t\tPairing.G1Point memory p2;\n\t\tp1.X = 1; p1.Y = 2;\n\t\tp2.X = 1; p2.Y = 2;\n\t\tPairing.G1Point memory explicit_sum = Pairing.add(p1, p2);\n\t\tPairing.G1Point memory scalar_prod = Pairing.mul(p1, 2);\n\t\treturn (explicit_sum.X == scalar_prod.X &&\n\t\t\texplicit_sum.Y == scalar_prod.Y);\n\t}\n\tfunction g() public returns (bool) {\n\t\tPairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));\n\t\t// should be zero\n\t\treturn (x.X == 0 && x.Y == 0);\n\t}\n\tfunction testMul() public returns (bool) {\n\t\tPairing.G1Point memory p;\n\t\t// @TODO The points here are reported to be not well-formed\n\t\tp.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;\n\t\tp.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;\n\t\tp = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);\n\t\treturn\n\t\t\tp.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&\n\t\t\tp.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;\n\t}\n\tfunction pair() public returns (bool) {\n\t\tPairing.G2Point memory fiveTimesP2 = Pairing.G2Point(\n\t\t\t[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],\n\t\t\t[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]\n\t\t);\n\t\t// The prime p in the base field F_p for G1\n\t\tuint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tPairing.G1Point[] memory g1points = new Pairing.G1Point[](2);\n\t\tPairing.G2Point[] memory g2points = new Pairing.G2Point[](2);\n\t\t// check e(5 P1, P2)e(-P1, 5 P2) == 1\n\t\tg1points[0] = Pairing.P1().mul(5);\n\t\tg1points[1] = Pairing.P1().negate();\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = fiveTimesP2;\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\t// check e(P1, P2)e(-P1, P2) == 1\n\t\tg1points[0] = Pairing.P1();\n\t\tg1points[1] = Pairing.P1();\n\t\tg1points[1].Y = p - g1points[1].Y;\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = Pairing.P2();\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tfunction verifyingKey() internal returns (VerifyingKey memory vk) {\n\t\tvk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);\n\t\tvk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);\n\t\tvk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);\n\t\tvk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);\n\t\tvk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);\n\t\tvk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);\n\t\tvk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);\n\t\tvk.IC = new Pairing.G1Point[](10);\n\t\tvk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);\n\t\tvk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);\n\t\tvk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);\n\t\tvk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);\n\t\tvk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);\n\t\tvk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);\n\t\tvk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);\n\t\tvk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);\n\t\tvk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);\n\t\tvk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);\n\t}\n\tfunction verify(uint[] memory input, Proof memory proof) internal returns (uint) {\n\t\tVerifyingKey memory vk = verifyingKey();\n\t\trequire(input.length + 1 == vk.IC.length);\n\t\t// Compute the linear combination vk_x\n\t\tPairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\t\tfor (uint i = 0; i < input.length; i++)\n\t\t\tvk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));\n\t\tvk_x = Pairing.add(vk_x, vk.IC[0]);\n\t\tif (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;\n\t\tif (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;\n\t\tif (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tproof.K, vk.gamma,\n\t\t\tPairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,\n\t\t\tPairing.negate(vk.gammaBeta1), proof.B\n\t\t)) return 4;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tPairing.add(vk_x, proof.A), proof.B,\n\t\t\tPairing.negate(proof.H), vk.Z,\n\t\t\tPairing.negate(proof.C), Pairing.P2()\n\t\t)) return 5;\n\t\treturn 0;\n\t}\n\tevent Verified(string);\n\tfunction verifyTx() public returns (bool) {\n\t\tuint[] memory input = new uint[](9);\n\t\tProof memory proof;\n\t\tproof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);\n\t\tproof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);\n\t\tproof.B = Pairing.G2Point(\n\t\t\t[8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],\n\t\t\t[15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);\n\t\tproof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);\n\t\tproof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);\n\t\tproof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);\n\t\tproof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);\n\t\tproof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);\n\t\tinput[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;\n\t\tinput[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;\n\t\tinput[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;\n\t\tinput[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;\n\t\tinput[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;\n\t\tinput[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;\n\t\tinput[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;\n\t\tinput[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;\n\t\tinput[8] = 18066496933330839731877828156604;\n\t\tif (verify(input, proof) == 0) {\n\t\t\temit Verified(\"Successfully verified.\");\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n/// Disabled because the point seems to be not well-formed, we need to find another example.\n/// testMul() -> true\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// library: Pairing\n// f() -> true\n// g() -> true\n// pair() -> true\n// gas irOptimized: 270409\n// gas legacy: 275219\n// gas legacyOptimized: 266862\n// verifyTx() -> true\n// ~ emit Verified(string): 0x20, 0x16, \"Successfully verified.\"\n// gas irOptimized: 785720\n// gas legacy: 801903\n// gas legacyOptimized: 770941\n" + }, + "prbmath_signed.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function div(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.div(y);\n }\n function exp(int256 x) external pure returns (int256 ret) {\n ret = x.exp();\n }\n function exp2(int256 x) external pure returns (int256 ret) {\n ret = x.exp2();\n }\n function gm(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.gm(y);\n }\n function log10(int256 x) external pure returns (int256 ret) {\n ret = x.log10();\n }\n function log2(int256 x) external pure returns (int256 ret) {\n ret = x.log2();\n }\n function mul(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.mul(y);\n }\n function pow(int256 x, uint256 y) external pure returns (int256 ret) {\n ret = x.pow(y);\n }\n function sqrt(int256 x) external pure returns (int256 ret) {\n ret = x.sqrt();\n }\n function benchmark(int256 x) external pure returns (int256 ret, int256 z1, int256 z2) {\n int256 y = x.mul(3).ceil();\n int256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 177903\n// gas irOptimized code: 1674400\n// gas legacy: 209723\n// gas legacy code: 2205000\n// gas legacyOptimized: 178012\n// gas legacyOptimized code: 1669600\n// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22137\n// gas legacy: 22767\n// gas legacyOptimized: 22282\n// exp(int256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24545\n// gas legacy: 25203\n// gas legacyOptimized: 24357\n// exp2(int256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24257\n// gas legacy: 24864\n// gas legacyOptimized: 24110\n// gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22970\n// gas legacy: 23228\n// gas legacyOptimized: 22683\n// log10(int256): 3141592653589793238 -> 4971498726941338506\n// gas irOptimized: 30609\n// gas legacy: 32934\n// gas legacyOptimized: 30323\n// log2(int256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28819\n// gas legacy: 31067\n// gas legacyOptimized: 28426\n// mul(int256,int256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22225\n// gas legacy: 22807\n// gas legacyOptimized: 22295\n// pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22635\n// gas legacy: 23508\n// gas legacyOptimized: 22921\n// sqrt(int256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22650\n// gas legacy: 22802\n// gas legacyOptimized: 22422\n// benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 36630\n// gas legacy: 36673\n// gas legacyOptimized: 34729\n" + }, + "prbmath_unsigned.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathUD60x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathUD60x18.sol\";\n\ncontract test {\n using PRBMathUD60x18 for uint256;\n\n function div(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.div(y);\n }\n function exp(uint256 x) external pure returns (uint256 ret) {\n ret = x.exp();\n }\n function exp2(uint256 x) external pure returns (uint256 ret) {\n ret = x.exp2();\n }\n function gm(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.gm(y);\n }\n function log10(uint256 x) external pure returns (uint256 ret) {\n ret = x.log10();\n }\n function log2(uint256 x) external pure returns (uint256 ret) {\n ret = x.log2();\n }\n function mul(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.mul(y);\n }\n function pow(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.pow(y);\n }\n function sqrt(uint256 x) external pure returns (uint256 ret) {\n ret = x.sqrt();\n }\n function benchmark(uint256 x) external pure returns (uint256 ret, uint256 z1, uint256 z2) {\n uint256 y = x.mul(3).ceil();\n uint256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 170626\n// gas irOptimized code: 1577400\n// gas legacy: 195206\n// gas legacy code: 1999000\n// gas legacyOptimized: 168857\n// gas legacyOptimized code: 1556200\n// div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22004\n// gas legacy: 22497\n// gas legacyOptimized: 22010\n// exp(uint256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24444\n// gas legacy: 25104\n// gas legacyOptimized: 24258\n// exp2(uint256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24198\n// gas legacy: 24814\n// gas legacyOptimized: 24062\n// gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22950\n// gas legacy: 23269\n// gas legacyOptimized: 22724\n// log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a\n// gas irOptimized: 30269\n// gas legacy: 32898\n// gas legacyOptimized: 29925\n// log2(uint256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28235\n// gas legacy: 30986\n// gas legacyOptimized: 28001\n// mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22048\n// gas legacy: 22604\n// gas legacyOptimized: 22090\n// pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22406\n// gas legacy: 23245\n// gas legacyOptimized: 22646\n// sqrt(uint256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22672\n// gas legacy: 22820\n// gas legacyOptimized: 22440\n// benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 35603\n// gas legacy: 35385\n// gas legacyOptimized: 33449\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi.sol b/examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi.sol new file mode 100644 index 00000000..70a3004a --- /dev/null +++ b/examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi.sol @@ -0,0 +1,45 @@ +==== ExternalSource: _prbmath/PRBMathCommon.sol ==== +==== ExternalSource: _prbmath/PRBMathSD59x18.sol ==== +==== Source: ramanujan_pi.sol ==== +import "_prbmath/PRBMathSD59x18.sol"; + +// The goal of this test file is to implement Ramanujan's pi approximation using various libraries. + +function factorial(uint n) pure returns (uint ret) { + ret = 1; + for (; n > 1; --n) + ret *= n; +} + +contract test { + using PRBMathSD59x18 for int256; + + function prb_scale(uint n) internal pure returns (int256 ret) { + // Scale to SD59x18 + ret = int256(n * 10e17); + } + + // This dumb implementation of Ramanujan series calculates 1/pi + function prb_pi() external pure returns (int256 ret) { + uint n = 6; // More than 6 iterations results in failure + for (uint k = 0; k < n; k++) { + int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4)); + int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k)); + ret += a.mul(b); + } + ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2))); + ret = prb_scale(1).div(ret); + } +} +// ---- +// constructor() +// gas irOptimized: 77816 +// gas irOptimized code: 307600 +// gas legacy: 92110 +// gas legacy code: 523600 +// gas legacyOptimized: 82667 +// gas legacyOptimized code: 369200 +// prb_pi() -> 3141592656369545286 +// gas irOptimized: 57478 +// gas legacy: 100657 +// gas legacyOptimized: 75735 diff --git a/examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi_standard_input.json b/examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi_standard_input.json new file mode 100644 index 00000000..7a51e208 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_ramanujan_pi/ramanujan_pi_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_snark/snark.sol b/examples/test/semanticTests/externalContracts_snark/snark.sol new file mode 100644 index 00000000..906279d1 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_snark/snark.sol @@ -0,0 +1,304 @@ +library Pairing { + struct G1Point { + uint X; + uint Y; + } + // Encoding of field elements is: X[0] * z + X[1] + struct G2Point { + uint[2] X; + uint[2] Y; + } + + /// @return the generator of G1 + function P1() internal returns (G1Point memory) { + return G1Point(1, 2); + } + + /// @return the generator of G2 + function P2() internal returns (G2Point memory) { + return G2Point( + [11559732032986387107991004021392285783925812861821192530917403151452391805634, + 10857046999023057135944570762232829481370756359578518086990519993285655852781], + [4082367875863433681332203403145435568316851327593401208105741076214120093531, + 8495653923123431417604973247489272438418190587263600148770280649306958101930] + ); + } + + /// @return the negation of p, i.e. p.add(p.negate()) should be zero. + function negate(G1Point memory p) internal returns (G1Point memory) { + // The prime q in the base field F_q for G1 + uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + if (p.X == 0 && p.Y == 0) + return G1Point(0, 0); + return G1Point(p.X, q - (p.Y % q)); + } + + /// @return r the sum of two points of G1 + function add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { + uint[4] memory input; + input[0] = p1.X; + input[1] = p1.Y; + input[2] = p2.X; + input[3] = p2.Y; + bool success; + assembly { + success := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60) + // Use "invalid" to make gas estimation work + switch success case 0 { invalid() } + } + require(success); + } + + /// @return r the product of a point on G1 and a scalar, i.e. + /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p. + function mul(G1Point memory p, uint s) internal returns (G1Point memory r) { + uint[3] memory input; + input[0] = p.X; + input[1] = p.Y; + input[2] = s; + bool success; + assembly { + success := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60) + // Use "invalid" to make gas estimation work + switch success case 0 { invalid() } + } + require(success); + } + + /// @return the result of computing the pairing check + /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1 + /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should + /// return true. + function pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) { + require(p1.length == p2.length); + uint elements = p1.length; + uint inputSize = p1.length * 6; + uint[] memory input = new uint[](inputSize); + for (uint i = 0; i < elements; i++) + { + input[i * 6 + 0] = p1[i].X; + input[i * 6 + 1] = p1[i].Y; + input[i * 6 + 2] = p2[i].X[0]; + input[i * 6 + 3] = p2[i].X[1]; + input[i * 6 + 4] = p2[i].Y[0]; + input[i * 6 + 5] = p2[i].Y[1]; + } + uint[1] memory out; + bool success; + assembly { + success := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) + // Use "invalid" to make gas estimation work + switch success case 0 { invalid() } + } + require(success); + return out[0] != 0; + } + function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) { + G1Point[] memory p1 = new G1Point[](2); + G2Point[] memory p2 = new G2Point[](2); + p1[0] = a1; + p1[1] = b1; + p2[0] = a2; + p2[1] = b2; + return pairing(p1, p2); + } + function pairingProd3( + G1Point memory a1, G2Point memory a2, + G1Point memory b1, G2Point memory b2, + G1Point memory c1, G2Point memory c2 + ) internal returns (bool) { + G1Point[] memory p1 = new G1Point[](3); + G2Point[] memory p2 = new G2Point[](3); + p1[0] = a1; + p1[1] = b1; + p1[2] = c1; + p2[0] = a2; + p2[1] = b2; + p2[2] = c2; + return pairing(p1, p2); + } + function pairingProd4( + G1Point memory a1, G2Point memory a2, + G1Point memory b1, G2Point memory b2, + G1Point memory c1, G2Point memory c2, + G1Point memory d1, G2Point memory d2 + ) internal returns (bool) { + G1Point[] memory p1 = new G1Point[](4); + G2Point[] memory p2 = new G2Point[](4); + p1[0] = a1; + p1[1] = b1; + p1[2] = c1; + p1[3] = d1; + p2[0] = a2; + p2[1] = b2; + p2[2] = c2; + p2[3] = d2; + return pairing(p1, p2); + } +} + +contract Test { + using Pairing for *; + struct VerifyingKey { + Pairing.G2Point A; + Pairing.G1Point B; + Pairing.G2Point C; + Pairing.G2Point gamma; + Pairing.G1Point gammaBeta1; + Pairing.G2Point gammaBeta2; + Pairing.G2Point Z; + Pairing.G1Point[] IC; + } + struct Proof { + Pairing.G1Point A; + Pairing.G1Point A_p; + Pairing.G2Point B; + Pairing.G1Point B_p; + Pairing.G1Point C; + Pairing.G1Point C_p; + Pairing.G1Point K; + Pairing.G1Point H; + } + function f() public returns (bool) { + Pairing.G1Point memory p1; + Pairing.G1Point memory p2; + p1.X = 1; p1.Y = 2; + p2.X = 1; p2.Y = 2; + Pairing.G1Point memory explicit_sum = Pairing.add(p1, p2); + Pairing.G1Point memory scalar_prod = Pairing.mul(p1, 2); + return (explicit_sum.X == scalar_prod.X && + explicit_sum.Y == scalar_prod.Y); + } + function g() public returns (bool) { + Pairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1())); + // should be zero + return (x.X == 0 && x.Y == 0); + } + function testMul() public returns (bool) { + Pairing.G1Point memory p; + // @TODO The points here are reported to be not well-formed + p.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726; + p.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057; + p = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521); + return + p.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 && + p.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803; + } + function pair() public returns (bool) { + Pairing.G2Point memory fiveTimesP2 = Pairing.G2Point( + [4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072], + [11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846] + ); + // The prime p in the base field F_p for G1 + uint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583; + Pairing.G1Point[] memory g1points = new Pairing.G1Point[](2); + Pairing.G2Point[] memory g2points = new Pairing.G2Point[](2); + // check e(5 P1, P2)e(-P1, 5 P2) == 1 + g1points[0] = Pairing.P1().mul(5); + g1points[1] = Pairing.P1().negate(); + g2points[0] = Pairing.P2(); + g2points[1] = fiveTimesP2; + if (!Pairing.pairing(g1points, g2points)) + return false; + // check e(P1, P2)e(-P1, P2) == 1 + g1points[0] = Pairing.P1(); + g1points[1] = Pairing.P1(); + g1points[1].Y = p - g1points[1].Y; + g2points[0] = Pairing.P2(); + g2points[1] = Pairing.P2(); + if (!Pairing.pairing(g1points, g2points)) + return false; + return true; + } + function verifyingKey() internal returns (VerifyingKey memory vk) { + vk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]); + vk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84); + vk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]); + vk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]); + vk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d); + vk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]); + vk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]); + vk.IC = new Pairing.G1Point[](10); + vk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf); + vk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb); + vk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db); + vk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1); + vk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b); + vk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7); + vk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4); + vk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e); + vk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e); + vk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30); + } + function verify(uint[] memory input, Proof memory proof) internal returns (uint) { + VerifyingKey memory vk = verifyingKey(); + require(input.length + 1 == vk.IC.length); + // Compute the linear combination vk_x + Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); + for (uint i = 0; i < input.length; i++) + vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i])); + vk_x = Pairing.add(vk_x, vk.IC[0]); + if (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1; + if (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2; + if (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3; + if (!Pairing.pairingProd3( + proof.K, vk.gamma, + Pairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2, + Pairing.negate(vk.gammaBeta1), proof.B + )) return 4; + if (!Pairing.pairingProd3( + Pairing.add(vk_x, proof.A), proof.B, + Pairing.negate(proof.H), vk.Z, + Pairing.negate(proof.C), Pairing.P2() + )) return 5; + return 0; + } + event Verified(string); + function verifyTx() public returns (bool) { + uint[] memory input = new uint[](9); + Proof memory proof; + proof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497); + proof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366); + proof.B = Pairing.G2Point( + [8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055], + [15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]); + proof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950); + proof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506); + proof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686); + proof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758); + proof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170); + input[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521; + input[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053; + input[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569; + input[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467; + input[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463; + input[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081; + input[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271; + input[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807; + input[8] = 18066496933330839731877828156604; + if (verify(input, proof) == 0) { + emit Verified("Successfully verified."); + return true; + } else { + return false; + } + } +} +/// Disabled because the point seems to be not well-formed, we need to find another example. +/// testMul() -> true +// +// ==== +// EVMVersion: >=constantinople +// ---- +// library: Pairing +// f() -> true +// g() -> true +// pair() -> true +// gas irOptimized: 270409 +// gas legacy: 275219 +// gas legacyOptimized: 266862 +// verifyTx() -> true +// ~ emit Verified(string): 0x20, 0x16, "Successfully verified." +// gas irOptimized: 785720 +// gas legacy: 801903 +// gas legacyOptimized: 770941 diff --git a/examples/test/semanticTests/externalContracts_snark/snark_standard_input.json b/examples/test/semanticTests/externalContracts_snark/snark_standard_input.json new file mode 100644 index 00000000..afe2a0e5 --- /dev/null +++ b/examples/test/semanticTests/externalContracts_snark/snark_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + }, + "deposit_contract.sol": { + "content": "// \u250f\u2501\u2501\u2501\u2513\u2501\u250f\u2513\u2501\u250f\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\n// \u2503\u250f\u2501\u2501\u251b\u250f\u251b\u2517\u2513\u2503\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2517\u2513\u250f\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\n// \u2503\u2517\u2501\u2501\u2513\u2517\u2513\u250f\u251b\u2503\u2517\u2501\u2513\u2517\u251b\u250f\u251b\u2503\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2513\u2517\u2513\u250f\u251b\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2517\u251b\u250f\u2501\u2501\u2513\u250f\u2501\u2513\u2501\u2517\u2513\u250f\u251b\u250f\u2501\u2513\u250f\u2501\u2501\u2513\u2501\u250f\u2501\u2501\u2513\u2517\u2513\u250f\u251b\n// \u2503\u250f\u2501\u2501\u251b\u2501\u2503\u2503\u2501\u2503\u250f\u2513\u2503\u250f\u2501\u251b\u250f\u251b\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u2501\u2501\u252b\u2523\u252b\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u250f\u2513\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2513\u2501\u2503\u2503\u2501\u2503\u250f\u251b\u2517\u2501\u2513\u2503\u2501\u2503\u250f\u2501\u251b\u2501\u2503\u2503\u2501\n// \u2503\u2517\u2501\u2501\u2513\u2501\u2503\u2517\u2513\u2503\u2503\u2503\u2503\u2503\u2503\u2517\u2501\u2513\u250f\u2513\u2503\u2517\u2501\u251b\u2503\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u251b\u2503\u2503\u2503\u2501\u252b\u2503\u2517\u251b\u2503\u2503\u2517\u251b\u2503\u2523\u2501\u2501\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u2517\u2501\u251b\u2503\u2503\u2517\u251b\u2503\u2503\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2503\u2503\u2501\u2503\u2517\u251b\u2517\u2513\u2503\u2517\u2501\u2513\u2501\u2503\u2517\u2513\n// \u2517\u2501\u2501\u2501\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2503\u250f\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2501\u2517\u2501\u251b\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2517\u251b\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n /// @notice A processed deposit event.\n event DepositEvent(\n bytes pubkey,\n bytes withdrawal_credentials,\n bytes amount,\n bytes signature,\n bytes index\n );\n\n /// @notice Submit a Phase 0 DepositData object.\n /// @param pubkey A BLS12-381 public key.\n /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n /// @param signature A BLS12-381 signature.\n /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n /// Used as a protection against malformed input.\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) external payable;\n\n /// @notice Query the current deposit root hash.\n /// @return The deposit root hash.\n function get_deposit_root() external view returns (bytes32);\n\n /// @notice Query the current deposit count.\n /// @return The deposit count encoded as a little endian 64-bit number.\n function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceId` and\n /// `interfaceId` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n // NOTE: this also ensures `deposit_count` will fit into 64-bits\n uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n uint256 deposit_count;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n constructor() public {\n // Compute hashes in empty sparse Merkle tree\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n }\n\n function get_deposit_root() override external view returns (bytes32) {\n bytes32 node;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1)\n node = sha256(abi.encodePacked(branch[height], node));\n else\n node = sha256(abi.encodePacked(node, zero_hashes[height]));\n size /= 2;\n }\n return sha256(abi.encodePacked(\n node,\n to_little_endian_64(uint64(deposit_count)),\n bytes24(0)\n ));\n }\n\n function get_deposit_count() override external view returns (bytes memory) {\n return to_little_endian_64(uint64(deposit_count));\n }\n\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) override external payable {\n // Extended ABI length checks since dynamic types are used.\n require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n // Check deposit amount\n require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n uint deposit_amount = msg.value / 1 gwei;\n require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n // Emit `DepositEvent` log\n bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n emit DepositEvent(\n pubkey,\n withdrawal_credentials,\n amount,\n signature,\n to_little_endian_64(uint64(deposit_count))\n );\n\n // Compute deposit data root (`DepositData` hash tree root)\n bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n bytes32 signature_root = sha256(abi.encodePacked(\n sha256(abi.encodePacked(signature[:64])),\n sha256(abi.encodePacked(signature[64:], bytes32(0)))\n ));\n bytes32 node = sha256(abi.encodePacked(\n sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n ));\n\n // Verify computed and expected deposit data roots match\n require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n // Add deposit data root to Merkle tree (update a single `branch` node)\n deposit_count += 1;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1) {\n branch[height] = node;\n return;\n }\n node = sha256(abi.encodePacked(branch[height], node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n }\n\n function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n" + }, + "snark.sol": { + "content": "library Pairing {\n\tstruct G1Point {\n\t\tuint X;\n\t\tuint Y;\n\t}\n\t// Encoding of field elements is: X[0] * z + X[1]\n\tstruct G2Point {\n\t\tuint[2] X;\n\t\tuint[2] Y;\n\t}\n\n\t/// @return the generator of G1\n\tfunction P1() internal returns (G1Point memory) {\n\t\treturn G1Point(1, 2);\n\t}\n\n\t/// @return the generator of G2\n\tfunction P2() internal returns (G2Point memory) {\n\t\treturn G2Point(\n\t\t\t[11559732032986387107991004021392285783925812861821192530917403151452391805634,\n\t\t\t 10857046999023057135944570762232829481370756359578518086990519993285655852781],\n\t\t\t[4082367875863433681332203403145435568316851327593401208105741076214120093531,\n\t\t\t 8495653923123431417604973247489272438418190587263600148770280649306958101930]\n\t\t);\n\t}\n\n\t/// @return the negation of p, i.e. p.add(p.negate()) should be zero.\n\tfunction negate(G1Point memory p) internal returns (G1Point memory) {\n\t\t// The prime q in the base field F_q for G1\n\t\tuint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tif (p.X == 0 && p.Y == 0)\n\t\t\treturn G1Point(0, 0);\n\t\treturn G1Point(p.X, q - (p.Y % q));\n\t}\n\n\t/// @return r the sum of two points of G1\n\tfunction add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {\n\t\tuint[4] memory input;\n\t\tinput[0] = p1.X;\n\t\tinput[1] = p1.Y;\n\t\tinput[2] = p2.X;\n\t\tinput[3] = p2.Y;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return r the product of a point on G1 and a scalar, i.e.\n\t/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n\tfunction mul(G1Point memory p, uint s) internal returns (G1Point memory r) {\n\t\tuint[3] memory input;\n\t\tinput[0] = p.X;\n\t\tinput[1] = p.Y;\n\t\tinput[2] = s;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return the result of computing the pairing check\n\t/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n\t/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n\t/// return true.\n\tfunction pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {\n\t\trequire(p1.length == p2.length);\n\t\tuint elements = p1.length;\n\t\tuint inputSize = p1.length * 6;\n\t\tuint[] memory input = new uint[](inputSize);\n\t\tfor (uint i = 0; i < elements; i++)\n\t\t{\n\t\t\tinput[i * 6 + 0] = p1[i].X;\n\t\t\tinput[i * 6 + 1] = p1[i].Y;\n\t\t\tinput[i * 6 + 2] = p2[i].X[0];\n\t\t\tinput[i * 6 + 3] = p2[i].X[1];\n\t\t\tinput[i * 6 + 4] = p2[i].Y[0];\n\t\t\tinput[i * 6 + 5] = p2[i].Y[1];\n\t\t}\n\t\tuint[1] memory out;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t\treturn out[0] != 0;\n\t}\n\tfunction pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](2);\n\t\tG2Point[] memory p2 = new G2Point[](2);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd3(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](3);\n\t\tG2Point[] memory p2 = new G2Point[](3);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd4(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2,\n\t\t\tG1Point memory d1, G2Point memory d2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](4);\n\t\tG2Point[] memory p2 = new G2Point[](4);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp1[3] = d1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\tp2[3] = d2;\n\t\treturn pairing(p1, p2);\n\t}\n}\n\ncontract Test {\n\tusing Pairing for *;\n\tstruct VerifyingKey {\n\t\tPairing.G2Point A;\n\t\tPairing.G1Point B;\n\t\tPairing.G2Point C;\n\t\tPairing.G2Point gamma;\n\t\tPairing.G1Point gammaBeta1;\n\t\tPairing.G2Point gammaBeta2;\n\t\tPairing.G2Point Z;\n\t\tPairing.G1Point[] IC;\n\t}\n\tstruct Proof {\n\t\tPairing.G1Point A;\n\t\tPairing.G1Point A_p;\n\t\tPairing.G2Point B;\n\t\tPairing.G1Point B_p;\n\t\tPairing.G1Point C;\n\t\tPairing.G1Point C_p;\n\t\tPairing.G1Point K;\n\t\tPairing.G1Point H;\n\t}\n\tfunction f() public returns (bool) {\n\t\tPairing.G1Point memory p1;\n\t\tPairing.G1Point memory p2;\n\t\tp1.X = 1; p1.Y = 2;\n\t\tp2.X = 1; p2.Y = 2;\n\t\tPairing.G1Point memory explicit_sum = Pairing.add(p1, p2);\n\t\tPairing.G1Point memory scalar_prod = Pairing.mul(p1, 2);\n\t\treturn (explicit_sum.X == scalar_prod.X &&\n\t\t\texplicit_sum.Y == scalar_prod.Y);\n\t}\n\tfunction g() public returns (bool) {\n\t\tPairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));\n\t\t// should be zero\n\t\treturn (x.X == 0 && x.Y == 0);\n\t}\n\tfunction testMul() public returns (bool) {\n\t\tPairing.G1Point memory p;\n\t\t// @TODO The points here are reported to be not well-formed\n\t\tp.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;\n\t\tp.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;\n\t\tp = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);\n\t\treturn\n\t\t\tp.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&\n\t\t\tp.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;\n\t}\n\tfunction pair() public returns (bool) {\n\t\tPairing.G2Point memory fiveTimesP2 = Pairing.G2Point(\n\t\t\t[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],\n\t\t\t[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]\n\t\t);\n\t\t// The prime p in the base field F_p for G1\n\t\tuint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tPairing.G1Point[] memory g1points = new Pairing.G1Point[](2);\n\t\tPairing.G2Point[] memory g2points = new Pairing.G2Point[](2);\n\t\t// check e(5 P1, P2)e(-P1, 5 P2) == 1\n\t\tg1points[0] = Pairing.P1().mul(5);\n\t\tg1points[1] = Pairing.P1().negate();\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = fiveTimesP2;\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\t// check e(P1, P2)e(-P1, P2) == 1\n\t\tg1points[0] = Pairing.P1();\n\t\tg1points[1] = Pairing.P1();\n\t\tg1points[1].Y = p - g1points[1].Y;\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = Pairing.P2();\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tfunction verifyingKey() internal returns (VerifyingKey memory vk) {\n\t\tvk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);\n\t\tvk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);\n\t\tvk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);\n\t\tvk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);\n\t\tvk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);\n\t\tvk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);\n\t\tvk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);\n\t\tvk.IC = new Pairing.G1Point[](10);\n\t\tvk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);\n\t\tvk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);\n\t\tvk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);\n\t\tvk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);\n\t\tvk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);\n\t\tvk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);\n\t\tvk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);\n\t\tvk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);\n\t\tvk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);\n\t\tvk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);\n\t}\n\tfunction verify(uint[] memory input, Proof memory proof) internal returns (uint) {\n\t\tVerifyingKey memory vk = verifyingKey();\n\t\trequire(input.length + 1 == vk.IC.length);\n\t\t// Compute the linear combination vk_x\n\t\tPairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\t\tfor (uint i = 0; i < input.length; i++)\n\t\t\tvk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));\n\t\tvk_x = Pairing.add(vk_x, vk.IC[0]);\n\t\tif (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;\n\t\tif (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;\n\t\tif (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tproof.K, vk.gamma,\n\t\t\tPairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,\n\t\t\tPairing.negate(vk.gammaBeta1), proof.B\n\t\t)) return 4;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tPairing.add(vk_x, proof.A), proof.B,\n\t\t\tPairing.negate(proof.H), vk.Z,\n\t\t\tPairing.negate(proof.C), Pairing.P2()\n\t\t)) return 5;\n\t\treturn 0;\n\t}\n\tevent Verified(string);\n\tfunction verifyTx() public returns (bool) {\n\t\tuint[] memory input = new uint[](9);\n\t\tProof memory proof;\n\t\tproof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);\n\t\tproof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);\n\t\tproof.B = Pairing.G2Point(\n\t\t\t[8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],\n\t\t\t[15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);\n\t\tproof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);\n\t\tproof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);\n\t\tproof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);\n\t\tproof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);\n\t\tproof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);\n\t\tinput[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;\n\t\tinput[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;\n\t\tinput[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;\n\t\tinput[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;\n\t\tinput[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;\n\t\tinput[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;\n\t\tinput[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;\n\t\tinput[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;\n\t\tinput[8] = 18066496933330839731877828156604;\n\t\tif (verify(input, proof) == 0) {\n\t\t\temit Verified(\"Successfully verified.\");\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n/// Disabled because the point seems to be not well-formed, we need to find another example.\n/// testMul() -> true\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// library: Pairing\n// f() -> true\n// g() -> true\n// pair() -> true\n// gas irOptimized: 270409\n// gas legacy: 275219\n// gas legacyOptimized: 266862\n// verifyTx() -> true\n// ~ emit Verified(string): 0x20, 0x16, \"Successfully verified.\"\n// gas irOptimized: 785720\n// gas legacy: 801903\n// gas legacyOptimized: 770941\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalContracts_strings/strings.sol b/examples/test/semanticTests/externalContracts_strings/strings.sol new file mode 100644 index 00000000..cb9616bb --- /dev/null +++ b/examples/test/semanticTests/externalContracts_strings/strings.sol @@ -0,0 +1,77 @@ +==== ExternalSource: _stringutils/stringutils.sol ==== +==== Source: strings.sol ==== +pragma abicoder v2; +import "_stringutils/stringutils.sol"; + +contract test { + using strings for bytes32; + using strings for string; + using strings for strings.slice; + + function toSlice(string memory a) external pure returns (strings.slice memory) { + return a.toSlice(); + } + + function roundtrip(string memory a) external pure returns (string memory) { + return a.toSlice().toString(); + } + + function utf8len(string memory a) external pure returns (uint) { + return a.toSlice().len(); + } + + function multiconcat(string memory a, uint count) public pure returns (string memory) { + strings.slice memory s = a.toSlice(); + for (uint i = 0; i < count; i++) { + s = s.concat(s).toSlice(); + } + return s.toString(); + } + + function benchmark(string memory text, bytes32 seed) external pure returns (uint) { + // Grow text. + text = multiconcat(text, 10); + + strings.slice memory a = text.toSlice(); + strings.slice memory b = seed.toSliceB32(); + + // Some heavy computation. + bool c = b.equals(a) || b.startsWith(a); + + // Join as a list. + strings.slice memory delim = c ? string(",").toSlice() : string(";").toSlice(); + strings.slice[] memory parts = new strings.slice[](2); + parts[0] = a; + parts[1] = b; + string memory d = delim.join(parts); + return d.toSlice().len(); + } +} +// ---- +// constructor() +// gas irOptimized: 95303 +// gas irOptimized code: 520000 +// gas legacy: 126346 +// gas legacy code: 932600 +// gas legacyOptimized: 102639 +// gas legacyOptimized code: 612400 +// toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 +// gas irOptimized: 22660 +// gas legacy: 23190 +// gas legacyOptimized: 22508 +// roundtrip(string): 0x20, 11, "hello world" -> 0x20, 11, "hello world" +// gas irOptimized: 23408 +// gas legacy: 23820 +// gas legacyOptimized: 23123 +// utf8len(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 4 # Input: "😃😃😃😃" # +// gas irOptimized: 24026 +// gas legacy: 25716 +// gas legacyOptimized: 24115 +// multiconcat(string,uint256): 0x40, 3, 11, "hello world" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times # +// gas irOptimized: 28440 +// gas legacy: 31621 +// gas legacyOptimized: 27914 +// benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 +// gas irOptimized: 1976778 +// gas legacy: 4234020 +// gas legacyOptimized: 2318668 diff --git a/examples/test/semanticTests/externalContracts_strings/strings_standard_input.json b/examples/test/semanticTests/externalContracts_strings/strings_standard_input.json new file mode 100644 index 00000000..8966271e --- /dev/null +++ b/examples/test/semanticTests/externalContracts_strings/strings_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "ramanujan_pi.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: ramanujan_pi.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\n// The goal of this test file is to implement Ramanujan's pi approximation using various libraries.\n\nfunction factorial(uint n) pure returns (uint ret) {\n ret = 1;\n for (; n > 1; --n)\n ret *= n;\n}\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function prb_scale(uint n) internal pure returns (int256 ret) {\n // Scale to SD59x18\n ret = int256(n * 10e17);\n }\n\n // This dumb implementation of Ramanujan series calculates 1/pi\n function prb_pi() external pure returns (int256 ret) {\n uint n = 6; // More than 6 iterations results in failure\n for (uint k = 0; k < n; k++) {\n int256 a = prb_scale(factorial(4 * k)).div(prb_scale(factorial(k)).pow(4));\n int256 b = (prb_scale(25390).mul(prb_scale(k)) + prb_scale(1103)).div(prb_scale(396).pow(4 * k));\n ret += a.mul(b);\n }\n ret = ret.mul(prb_scale(2).sqrt().mul(prb_scale(2)).div(prb_scale(99).pow(2)));\n ret = prb_scale(1).div(ret);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 77816\n// gas irOptimized code: 307600\n// gas legacy: 92110\n// gas legacy code: 523600\n// gas legacyOptimized: 82667\n// gas legacyOptimized code: 369200\n// prb_pi() -> 3141592656369545286\n// gas irOptimized: 57478\n// gas legacy: 100657\n// gas legacyOptimized: 75735\n" + }, + "FixedFeeRegistrar.sol": { + "content": "//sol FixedFeeRegistrar\n// Simple global registrar with fixed-fee reservations.\n// @authors:\n// Gav Wood \n\npragma solidity >=0.4.0 <0.9.0;\n\nabstract contract Registrar {\n\tevent Changed(string indexed name);\n\n\tfunction owner(string memory _name) public virtual view returns (address o_owner);\n\tfunction addr(string memory _name) public virtual view returns (address o_address);\n\tfunction subRegistrar(string memory _name) virtual public view returns (address o_subRegistrar);\n\tfunction content(string memory _name) public virtual view returns (bytes32 o_content);\n}\n\ncontract FixedFeeRegistrar is Registrar {\n\tstruct Record {\n\t\taddress addr;\n\t\taddress subRegistrar;\n\t\tbytes32 content;\n\t\taddress owner;\n\t}\n\n\tmodifier onlyrecordowner(string memory _name) { if (m_record(_name).owner == msg.sender) _; }\n\n\tfunction reserve(string memory _name) public payable {\n\t\tRecord storage rec = m_record(_name);\n\t\tif (rec.owner == 0x0000000000000000000000000000000000000000 && msg.value >= c_fee) {\n\t\t\trec.owner = msg.sender;\n\t\t\temit Changed(_name);\n\t\t}\n\t}\n\tfunction disown(string memory _name, address payable _refund) onlyrecordowner(_name) public {\n\t\tdelete m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t\tif (!_refund.send(c_fee))\n\t\t\trevert();\n\t\temit Changed(_name);\n\t}\n\tfunction transfer(string memory _name, address _newOwner) onlyrecordowner(_name) public {\n\t\tm_record(_name).owner = _newOwner;\n\t\temit Changed(_name);\n\t}\n\tfunction setAddr(string memory _name, address _a) onlyrecordowner(_name) public {\n\t\tm_record(_name).addr = _a;\n\t\temit Changed(_name);\n\t}\n\tfunction setSubRegistrar(string memory _name, address _registrar) onlyrecordowner(_name) public {\n\t\tm_record(_name).subRegistrar = _registrar;\n\t\temit Changed(_name);\n\t}\n\tfunction setContent(string memory _name, bytes32 _content) onlyrecordowner(_name) public {\n\t\tm_record(_name).content = _content;\n\t\temit Changed(_name);\n\t}\n\n\tfunction record(string memory _name) public view returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {\n\t\tRecord storage rec = m_record(_name);\n\t\to_addr = rec.addr;\n\t\to_subRegistrar = rec.subRegistrar;\n\t\to_content = rec.content;\n\t\to_owner = rec.owner;\n\t}\n\tfunction addr(string memory _name) public override view returns (address) { return m_record(_name).addr; }\n\tfunction subRegistrar(string memory _name) public override view returns (address) { return m_record(_name).subRegistrar; }\n\tfunction content(string memory _name) public override view returns (bytes32) { return m_record(_name).content; }\n\tfunction owner(string memory _name) public override view returns (address) { return m_record(_name).owner; }\n\n\tRecord[2**253] m_recordData;\n\tfunction m_record(string memory _name) view internal returns (Record storage o_record) {\n\t\treturn m_recordData[uint(keccak256(bytes(_name))) / 8];\n\t}\n\tuint constant c_fee = 69 ether;\n}\n// ----\n// constructor()\n// gas irOptimized: 78076\n// gas irOptimized code: 307400\n// gas legacy: 115395\n// gas legacy code: 792400\n// gas legacyOptimized: 84598\n// gas legacyOptimized code: 388000\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// gas irOptimized: 45967\n// gas legacy: 46842\n// gas legacyOptimized: 46091\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 70 ether: 0x20, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0x1212121212121212121212121212120000000012\n// reserve(string), 68 ether: 0x20, 3, \"ghi\" ->\n// owner(string): 0x20, 3, \"ghi\" -> 0\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// reserve(string), 69 ether: 0x20, 3, \"abc\" ->\n// owner(string): 0x20, 3, \"abc\" -> 0x1212121212121212121212121212120000000012\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// setContent(string,bytes32): 0x40, 0, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// transfer(string,address): 0x40, 555, 3, \"abc\" ->\n// ~ emit Changed(string): #0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45\n// owner(string): 0x20, 3, \"abc\" -> 555\n// content(string): 0x20, 3, \"abc\" -> 0x00\n// setContent(string,bytes32): 0x40, 333, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setAddr(string,address): 0x40, 124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// setSubRegistrar(string,address): 0x40, 125, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// content(string): 0x20, 3, \"def\" -> 333\n// addr(string): 0x20, 3, \"def\" -> 124\n// subRegistrar(string): 0x20, 3, \"def\" -> 125\n// balance: 0x124 -> 0\n// disown(string,address): 0x40, 0x124, 3, \"def\" ->\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// balance: 0x124 -> 0\n// ~ emit Changed(string): #0x34607c9bbfeb9c23509680f04363f298fdb0b5f9abe327304ecd1daca08cda9c\n// owner(string): 0x20, 3, \"def\" -> 0\n// content(string): 0x20, 3, \"def\" -> 0\n// addr(string): 0x20, 3, \"def\" -> 0\n// subRegistrar(string): 0x20, 3, \"def\" -> 0\n" + }, + "deposit_contract.sol": { + "content": "// \u250f\u2501\u2501\u2501\u2513\u2501\u250f\u2513\u2501\u250f\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u250f\u2501\u2501\u2501\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u2513\u2501\n// \u2503\u250f\u2501\u2501\u251b\u250f\u251b\u2517\u2513\u2503\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2517\u2513\u250f\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u250f\u2501\u2513\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u2513\n// \u2503\u2517\u2501\u2501\u2513\u2517\u2513\u250f\u251b\u2503\u2517\u2501\u2513\u2517\u251b\u250f\u251b\u2503\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2501\u2501\u2513\u250f\u2513\u2517\u2513\u250f\u251b\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2517\u251b\u250f\u2501\u2501\u2513\u250f\u2501\u2513\u2501\u2517\u2513\u250f\u251b\u250f\u2501\u2513\u250f\u2501\u2501\u2513\u2501\u250f\u2501\u2501\u2513\u2517\u2513\u250f\u251b\n// \u2503\u250f\u2501\u2501\u251b\u2501\u2503\u2503\u2501\u2503\u250f\u2513\u2503\u250f\u2501\u251b\u250f\u251b\u2501\u2501\u2503\u2503\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2503\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2503\u2503\u2501\u2501\u252b\u2523\u252b\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u250f\u2513\u2503\u250f\u2513\u2503\u2503\u250f\u2513\u2513\u2501\u2503\u2503\u2501\u2503\u250f\u251b\u2517\u2501\u2513\u2503\u2501\u2503\u250f\u2501\u251b\u2501\u2503\u2503\u2501\n// \u2503\u2517\u2501\u2501\u2513\u2501\u2503\u2517\u2513\u2503\u2503\u2503\u2503\u2503\u2503\u2517\u2501\u2513\u250f\u2513\u2503\u2517\u2501\u251b\u2503\u2501\u2501\u2501\u2501\u250f\u251b\u2517\u251b\u2503\u2503\u2503\u2501\u252b\u2503\u2517\u251b\u2503\u2503\u2517\u251b\u2503\u2523\u2501\u2501\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2501\u2501\u2501\u2501\u2503\u2517\u2501\u251b\u2503\u2503\u2517\u251b\u2503\u2503\u2503\u2503\u2503\u2501\u2503\u2517\u2513\u2503\u2503\u2501\u2503\u2517\u251b\u2517\u2513\u2503\u2517\u2501\u2513\u2501\u2503\u2517\u2513\n// \u2517\u2501\u2501\u2501\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2517\u251b\u2517\u2501\u2501\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2503\u250f\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2501\u2501\u2501\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2517\u251b\u2517\u251b\u2501\u2517\u2501\u251b\u2517\u251b\u2501\u2517\u2501\u2501\u2501\u251b\u2517\u2501\u2501\u251b\u2501\u2517\u2501\u251b\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2503\u2503\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n// \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2517\u251b\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n// SPDX-License-Identifier: CC0-1.0\n\n// This interface is designed to be compatible with the Vyper version.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ninterface IDepositContract {\n /// @notice A processed deposit event.\n event DepositEvent(\n bytes pubkey,\n bytes withdrawal_credentials,\n bytes amount,\n bytes signature,\n bytes index\n );\n\n /// @notice Submit a Phase 0 DepositData object.\n /// @param pubkey A BLS12-381 public key.\n /// @param withdrawal_credentials Commitment to a public key for withdrawals.\n /// @param signature A BLS12-381 signature.\n /// @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.\n /// Used as a protection against malformed input.\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) external payable;\n\n /// @notice Query the current deposit root hash.\n /// @return The deposit root hash.\n function get_deposit_root() external view returns (bytes32);\n\n /// @notice Query the current deposit count.\n /// @return The deposit count encoded as a little endian 64-bit number.\n function get_deposit_count() external view returns (bytes memory);\n}\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceId The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceId` and\n /// `interfaceId` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceId) external pure returns (bool);\n}\n\n// This is a rewrite of the Vyper Eth2.0 deposit contract in Solidity.\n// It tries to stay as close as possible to the original source code.\n/// @notice This is the Ethereum 2.0 deposit contract interface.\n/// For more information see the Phase 0 specification under https://github.com/ethereum/eth2.0-specs\ncontract DepositContract is IDepositContract, ERC165 {\n uint constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;\n // NOTE: this also ensures `deposit_count` will fit into 64-bits\n uint constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] branch;\n uint256 deposit_count;\n\n bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] zero_hashes;\n\n constructor() public {\n // Compute hashes in empty sparse Merkle tree\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++)\n zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));\n }\n\n function get_deposit_root() override external view returns (bytes32) {\n bytes32 node;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1)\n node = sha256(abi.encodePacked(branch[height], node));\n else\n node = sha256(abi.encodePacked(node, zero_hashes[height]));\n size /= 2;\n }\n return sha256(abi.encodePacked(\n node,\n to_little_endian_64(uint64(deposit_count)),\n bytes24(0)\n ));\n }\n\n function get_deposit_count() override external view returns (bytes memory) {\n return to_little_endian_64(uint64(deposit_count));\n }\n\n function deposit(\n bytes calldata pubkey,\n bytes calldata withdrawal_credentials,\n bytes calldata signature,\n bytes32 deposit_data_root\n ) override external payable {\n // Extended ABI length checks since dynamic types are used.\n require(pubkey.length == 48, \"DepositContract: invalid pubkey length\");\n require(withdrawal_credentials.length == 32, \"DepositContract: invalid withdrawal_credentials length\");\n require(signature.length == 96, \"DepositContract: invalid signature length\");\n\n // Check deposit amount\n require(msg.value >= 1 ether, \"DepositContract: deposit value too low\");\n require(msg.value % 1 gwei == 0, \"DepositContract: deposit value not multiple of gwei\");\n uint deposit_amount = msg.value / 1 gwei;\n require(deposit_amount <= type(uint64).max, \"DepositContract: deposit value too high\");\n\n // Emit `DepositEvent` log\n bytes memory amount = to_little_endian_64(uint64(deposit_amount));\n emit DepositEvent(\n pubkey,\n withdrawal_credentials,\n amount,\n signature,\n to_little_endian_64(uint64(deposit_count))\n );\n\n // Compute deposit data root (`DepositData` hash tree root)\n bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));\n bytes32 signature_root = sha256(abi.encodePacked(\n sha256(abi.encodePacked(signature[:64])),\n sha256(abi.encodePacked(signature[64:], bytes32(0)))\n ));\n bytes32 node = sha256(abi.encodePacked(\n sha256(abi.encodePacked(pubkey_root, withdrawal_credentials)),\n sha256(abi.encodePacked(amount, bytes24(0), signature_root))\n ));\n\n // Verify computed and expected deposit data roots match\n require(node == deposit_data_root, \"DepositContract: reconstructed DepositData does not match supplied deposit_data_root\");\n\n // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)\n require(deposit_count < MAX_DEPOSIT_COUNT, \"DepositContract: merkle tree full\");\n\n // Add deposit data root to Merkle tree (update a single `branch` node)\n deposit_count += 1;\n uint size = deposit_count;\n for (uint height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {\n if ((size & 1) == 1) {\n branch[height] = node;\n return;\n }\n node = sha256(abi.encodePacked(branch[height], node));\n size /= 2;\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {\n return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;\n }\n\n function to_little_endian_64(uint64 value) internal pure returns (bytes memory ret) {\n ret = new bytes(8);\n bytes8 bytesValue = bytes8(value);\n // Byteswapping during copying to bytes.\n ret[0] = bytesValue[7];\n ret[1] = bytesValue[6];\n ret[2] = bytesValue[5];\n ret[3] = bytesValue[4];\n ret[4] = bytesValue[3];\n ret[5] = bytesValue[2];\n ret[6] = bytesValue[1];\n ret[7] = bytesValue[0];\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 809570\n// gas irOptimized code: 558000\n// gas legacy: 920228\n// gas legacy code: 1438800\n// gas legacyOptimized: 848699\n// gas legacyOptimized code: 878200\n// supportsInterface(bytes4): 0x0 -> 0\n// supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 #\n// supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id #\n// supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit #\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input #\n// get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e\n// gas irOptimized: 109178\n// gas legacy: 142741\n// gas legacyOptimized: 117558\n// get_deposit_count() -> 0x20, 8, 0\n// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00\n// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000\n// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #\n// ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee\n// gas irOptimized: 109174\n// gas legacy: 142750\n// gas legacyOptimized: 117570\n// get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000\n" + }, + "snark.sol": { + "content": "library Pairing {\n\tstruct G1Point {\n\t\tuint X;\n\t\tuint Y;\n\t}\n\t// Encoding of field elements is: X[0] * z + X[1]\n\tstruct G2Point {\n\t\tuint[2] X;\n\t\tuint[2] Y;\n\t}\n\n\t/// @return the generator of G1\n\tfunction P1() internal returns (G1Point memory) {\n\t\treturn G1Point(1, 2);\n\t}\n\n\t/// @return the generator of G2\n\tfunction P2() internal returns (G2Point memory) {\n\t\treturn G2Point(\n\t\t\t[11559732032986387107991004021392285783925812861821192530917403151452391805634,\n\t\t\t 10857046999023057135944570762232829481370756359578518086990519993285655852781],\n\t\t\t[4082367875863433681332203403145435568316851327593401208105741076214120093531,\n\t\t\t 8495653923123431417604973247489272438418190587263600148770280649306958101930]\n\t\t);\n\t}\n\n\t/// @return the negation of p, i.e. p.add(p.negate()) should be zero.\n\tfunction negate(G1Point memory p) internal returns (G1Point memory) {\n\t\t// The prime q in the base field F_q for G1\n\t\tuint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tif (p.X == 0 && p.Y == 0)\n\t\t\treturn G1Point(0, 0);\n\t\treturn G1Point(p.X, q - (p.Y % q));\n\t}\n\n\t/// @return r the sum of two points of G1\n\tfunction add(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {\n\t\tuint[4] memory input;\n\t\tinput[0] = p1.X;\n\t\tinput[1] = p1.Y;\n\t\tinput[2] = p2.X;\n\t\tinput[3] = p2.Y;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return r the product of a point on G1 and a scalar, i.e.\n\t/// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.\n\tfunction mul(G1Point memory p, uint s) internal returns (G1Point memory r) {\n\t\tuint[3] memory input;\n\t\tinput[0] = p.X;\n\t\tinput[1] = p.Y;\n\t\tinput[2] = s;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t}\n\n\t/// @return the result of computing the pairing check\n\t/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1\n\t/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should\n\t/// return true.\n\tfunction pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {\n\t\trequire(p1.length == p2.length);\n\t\tuint elements = p1.length;\n\t\tuint inputSize = p1.length * 6;\n\t\tuint[] memory input = new uint[](inputSize);\n\t\tfor (uint i = 0; i < elements; i++)\n\t\t{\n\t\t\tinput[i * 6 + 0] = p1[i].X;\n\t\t\tinput[i * 6 + 1] = p1[i].Y;\n\t\t\tinput[i * 6 + 2] = p2[i].X[0];\n\t\t\tinput[i * 6 + 3] = p2[i].X[1];\n\t\t\tinput[i * 6 + 4] = p2[i].Y[0];\n\t\t\tinput[i * 6 + 5] = p2[i].Y[1];\n\t\t}\n\t\tuint[1] memory out;\n\t\tbool success;\n\t\tassembly {\n\t\t\tsuccess := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)\n\t\t\t// Use \"invalid\" to make gas estimation work\n\t\t\tswitch success case 0 { invalid() }\n\t\t}\n\t\trequire(success);\n\t\treturn out[0] != 0;\n\t}\n\tfunction pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](2);\n\t\tG2Point[] memory p2 = new G2Point[](2);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd3(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](3);\n\t\tG2Point[] memory p2 = new G2Point[](3);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\treturn pairing(p1, p2);\n\t}\n\tfunction pairingProd4(\n\t\tG1Point memory a1, G2Point memory a2,\n\t\tG1Point memory b1, G2Point memory b2,\n\t\tG1Point memory c1, G2Point memory c2,\n\t\t\tG1Point memory d1, G2Point memory d2\n\t) internal returns (bool) {\n\t\tG1Point[] memory p1 = new G1Point[](4);\n\t\tG2Point[] memory p2 = new G2Point[](4);\n\t\tp1[0] = a1;\n\t\tp1[1] = b1;\n\t\tp1[2] = c1;\n\t\tp1[3] = d1;\n\t\tp2[0] = a2;\n\t\tp2[1] = b2;\n\t\tp2[2] = c2;\n\t\tp2[3] = d2;\n\t\treturn pairing(p1, p2);\n\t}\n}\n\ncontract Test {\n\tusing Pairing for *;\n\tstruct VerifyingKey {\n\t\tPairing.G2Point A;\n\t\tPairing.G1Point B;\n\t\tPairing.G2Point C;\n\t\tPairing.G2Point gamma;\n\t\tPairing.G1Point gammaBeta1;\n\t\tPairing.G2Point gammaBeta2;\n\t\tPairing.G2Point Z;\n\t\tPairing.G1Point[] IC;\n\t}\n\tstruct Proof {\n\t\tPairing.G1Point A;\n\t\tPairing.G1Point A_p;\n\t\tPairing.G2Point B;\n\t\tPairing.G1Point B_p;\n\t\tPairing.G1Point C;\n\t\tPairing.G1Point C_p;\n\t\tPairing.G1Point K;\n\t\tPairing.G1Point H;\n\t}\n\tfunction f() public returns (bool) {\n\t\tPairing.G1Point memory p1;\n\t\tPairing.G1Point memory p2;\n\t\tp1.X = 1; p1.Y = 2;\n\t\tp2.X = 1; p2.Y = 2;\n\t\tPairing.G1Point memory explicit_sum = Pairing.add(p1, p2);\n\t\tPairing.G1Point memory scalar_prod = Pairing.mul(p1, 2);\n\t\treturn (explicit_sum.X == scalar_prod.X &&\n\t\t\texplicit_sum.Y == scalar_prod.Y);\n\t}\n\tfunction g() public returns (bool) {\n\t\tPairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));\n\t\t// should be zero\n\t\treturn (x.X == 0 && x.Y == 0);\n\t}\n\tfunction testMul() public returns (bool) {\n\t\tPairing.G1Point memory p;\n\t\t// @TODO The points here are reported to be not well-formed\n\t\tp.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;\n\t\tp.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;\n\t\tp = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);\n\t\treturn\n\t\t\tp.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&\n\t\t\tp.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;\n\t}\n\tfunction pair() public returns (bool) {\n\t\tPairing.G2Point memory fiveTimesP2 = Pairing.G2Point(\n\t\t\t[4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],\n\t\t\t[11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]\n\t\t);\n\t\t// The prime p in the base field F_p for G1\n\t\tuint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\t\tPairing.G1Point[] memory g1points = new Pairing.G1Point[](2);\n\t\tPairing.G2Point[] memory g2points = new Pairing.G2Point[](2);\n\t\t// check e(5 P1, P2)e(-P1, 5 P2) == 1\n\t\tg1points[0] = Pairing.P1().mul(5);\n\t\tg1points[1] = Pairing.P1().negate();\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = fiveTimesP2;\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\t// check e(P1, P2)e(-P1, P2) == 1\n\t\tg1points[0] = Pairing.P1();\n\t\tg1points[1] = Pairing.P1();\n\t\tg1points[1].Y = p - g1points[1].Y;\n\t\tg2points[0] = Pairing.P2();\n\t\tg2points[1] = Pairing.P2();\n\t\tif (!Pairing.pairing(g1points, g2points))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\tfunction verifyingKey() internal returns (VerifyingKey memory vk) {\n\t\tvk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);\n\t\tvk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);\n\t\tvk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);\n\t\tvk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);\n\t\tvk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);\n\t\tvk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);\n\t\tvk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);\n\t\tvk.IC = new Pairing.G1Point[](10);\n\t\tvk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);\n\t\tvk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);\n\t\tvk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);\n\t\tvk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);\n\t\tvk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);\n\t\tvk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);\n\t\tvk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);\n\t\tvk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);\n\t\tvk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);\n\t\tvk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);\n\t}\n\tfunction verify(uint[] memory input, Proof memory proof) internal returns (uint) {\n\t\tVerifyingKey memory vk = verifyingKey();\n\t\trequire(input.length + 1 == vk.IC.length);\n\t\t// Compute the linear combination vk_x\n\t\tPairing.G1Point memory vk_x = Pairing.G1Point(0, 0);\n\t\tfor (uint i = 0; i < input.length; i++)\n\t\t\tvk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));\n\t\tvk_x = Pairing.add(vk_x, vk.IC[0]);\n\t\tif (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;\n\t\tif (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;\n\t\tif (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tproof.K, vk.gamma,\n\t\t\tPairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,\n\t\t\tPairing.negate(vk.gammaBeta1), proof.B\n\t\t)) return 4;\n\t\tif (!Pairing.pairingProd3(\n\t\t\tPairing.add(vk_x, proof.A), proof.B,\n\t\t\tPairing.negate(proof.H), vk.Z,\n\t\t\tPairing.negate(proof.C), Pairing.P2()\n\t\t)) return 5;\n\t\treturn 0;\n\t}\n\tevent Verified(string);\n\tfunction verifyTx() public returns (bool) {\n\t\tuint[] memory input = new uint[](9);\n\t\tProof memory proof;\n\t\tproof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);\n\t\tproof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);\n\t\tproof.B = Pairing.G2Point(\n\t\t\t[8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],\n\t\t\t[15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);\n\t\tproof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);\n\t\tproof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);\n\t\tproof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);\n\t\tproof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);\n\t\tproof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);\n\t\tinput[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;\n\t\tinput[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;\n\t\tinput[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;\n\t\tinput[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;\n\t\tinput[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;\n\t\tinput[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;\n\t\tinput[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;\n\t\tinput[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;\n\t\tinput[8] = 18066496933330839731877828156604;\n\t\tif (verify(input, proof) == 0) {\n\t\t\temit Verified(\"Successfully verified.\");\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n}\n/// Disabled because the point seems to be not well-formed, we need to find another example.\n/// testMul() -> true\n//\n// ====\n// EVMVersion: >=constantinople\n// ----\n// library: Pairing\n// f() -> true\n// g() -> true\n// pair() -> true\n// gas irOptimized: 270409\n// gas legacy: 275219\n// gas legacyOptimized: 266862\n// verifyTx() -> true\n// ~ emit Verified(string): 0x20, 0x16, \"Successfully verified.\"\n// gas irOptimized: 785720\n// gas legacy: 801903\n// gas legacyOptimized: 770941\n" + }, + "prbmath_signed.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathSD59x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathSD59x18.sol\";\n\ncontract test {\n using PRBMathSD59x18 for int256;\n\n function div(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.div(y);\n }\n function exp(int256 x) external pure returns (int256 ret) {\n ret = x.exp();\n }\n function exp2(int256 x) external pure returns (int256 ret) {\n ret = x.exp2();\n }\n function gm(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.gm(y);\n }\n function log10(int256 x) external pure returns (int256 ret) {\n ret = x.log10();\n }\n function log2(int256 x) external pure returns (int256 ret) {\n ret = x.log2();\n }\n function mul(int256 x, int256 y) external pure returns (int256 ret) {\n ret = x.mul(y);\n }\n function pow(int256 x, uint256 y) external pure returns (int256 ret) {\n ret = x.pow(y);\n }\n function sqrt(int256 x) external pure returns (int256 ret) {\n ret = x.sqrt();\n }\n function benchmark(int256 x) external pure returns (int256 ret, int256 z1, int256 z2) {\n int256 y = x.mul(3).ceil();\n int256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 177903\n// gas irOptimized code: 1674400\n// gas legacy: 209723\n// gas legacy code: 2205000\n// gas legacyOptimized: 178012\n// gas legacyOptimized code: 1669600\n// div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22137\n// gas legacy: 22767\n// gas legacyOptimized: 22282\n// exp(int256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24545\n// gas legacy: 25203\n// gas legacyOptimized: 24357\n// exp2(int256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24257\n// gas legacy: 24864\n// gas legacyOptimized: 24110\n// gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22970\n// gas legacy: 23228\n// gas legacyOptimized: 22683\n// log10(int256): 3141592653589793238 -> 4971498726941338506\n// gas irOptimized: 30609\n// gas legacy: 32934\n// gas legacyOptimized: 30323\n// log2(int256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28819\n// gas legacy: 31067\n// gas legacyOptimized: 28426\n// mul(int256,int256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22225\n// gas legacy: 22807\n// gas legacyOptimized: 22295\n// pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22635\n// gas legacy: 23508\n// gas legacyOptimized: 22921\n// sqrt(int256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22650\n// gas legacy: 22802\n// gas legacyOptimized: 22422\n// benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 36630\n// gas legacy: 36673\n// gas legacyOptimized: 34729\n" + }, + "prbmath_unsigned.sol": { + "content": "==== ExternalSource: _prbmath/PRBMathCommon.sol ====\n==== ExternalSource: _prbmath/PRBMathUD60x18.sol ====\n==== Source: prbmath.sol ====\nimport \"_prbmath/PRBMathUD60x18.sol\";\n\ncontract test {\n using PRBMathUD60x18 for uint256;\n\n function div(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.div(y);\n }\n function exp(uint256 x) external pure returns (uint256 ret) {\n ret = x.exp();\n }\n function exp2(uint256 x) external pure returns (uint256 ret) {\n ret = x.exp2();\n }\n function gm(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.gm(y);\n }\n function log10(uint256 x) external pure returns (uint256 ret) {\n ret = x.log10();\n }\n function log2(uint256 x) external pure returns (uint256 ret) {\n ret = x.log2();\n }\n function mul(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.mul(y);\n }\n function pow(uint256 x, uint256 y) external pure returns (uint256 ret) {\n ret = x.pow(y);\n }\n function sqrt(uint256 x) external pure returns (uint256 ret) {\n ret = x.sqrt();\n }\n function benchmark(uint256 x) external pure returns (uint256 ret, uint256 z1, uint256 z2) {\n uint256 y = x.mul(3).ceil();\n uint256 z = y.div(x);\n for (uint i = 0; i < 10; i++)\n z = z.sqrt();\n ret = z;\n\n // Check precision\n z1 = z.ceil();\n z2 = z.sqrt().pow(2).ceil();\n assert(z1 == z2);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 170626\n// gas irOptimized code: 1577400\n// gas legacy: 195206\n// gas legacy code: 1999000\n// gas legacyOptimized: 168857\n// gas legacyOptimized code: 1556200\n// div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328\n// gas irOptimized: 22004\n// gas legacy: 22497\n// gas legacyOptimized: 22010\n// exp(uint256): 3141592653589793238 -> 23140692632779268978\n// gas irOptimized: 24444\n// gas legacy: 25104\n// gas legacyOptimized: 24258\n// exp2(uint256): 3141592653589793238 -> 8824977827076287620\n// gas irOptimized: 24198\n// gas legacy: 24814\n// gas legacyOptimized: 24062\n// gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601\n// gas irOptimized: 22950\n// gas legacy: 23269\n// gas legacyOptimized: 22724\n// log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a\n// gas irOptimized: 30269\n// gas legacy: 32898\n// gas legacyOptimized: 29925\n// log2(uint256): 3141592653589793238 -> 1651496129472318782\n// gas irOptimized: 28235\n// gas legacy: 30986\n// gas legacyOptimized: 28001\n// mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637\n// gas irOptimized: 22048\n// gas legacy: 22604\n// gas legacyOptimized: 22090\n// pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040\n// gas irOptimized: 22406\n// gas legacy: 23245\n// gas legacyOptimized: 22646\n// sqrt(uint256): 3141592653589793238 -> 1772453850905516027\n// gas irOptimized: 22672\n// gas legacy: 22820\n// gas legacyOptimized: 22440\n// benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000\n// gas irOptimized: 35603\n// gas legacy: 35385\n// gas legacyOptimized: 33449\n" + }, + "strings.sol": { + "content": "==== ExternalSource: _stringutils/stringutils.sol ====\n==== Source: strings.sol ====\npragma abicoder v2;\nimport \"_stringutils/stringutils.sol\";\n\ncontract test {\n using strings for bytes32;\n using strings for string;\n using strings for strings.slice;\n\n function toSlice(string memory a) external pure returns (strings.slice memory) {\n return a.toSlice();\n }\n\n function roundtrip(string memory a) external pure returns (string memory) {\n return a.toSlice().toString();\n }\n\n function utf8len(string memory a) external pure returns (uint) {\n return a.toSlice().len();\n }\n\n function multiconcat(string memory a, uint count) public pure returns (string memory) {\n strings.slice memory s = a.toSlice();\n for (uint i = 0; i < count; i++) {\n s = s.concat(s).toSlice();\n }\n return s.toString();\n }\n\n function benchmark(string memory text, bytes32 seed) external pure returns (uint) {\n // Grow text.\n text = multiconcat(text, 10);\n\n strings.slice memory a = text.toSlice();\n strings.slice memory b = seed.toSliceB32();\n\n // Some heavy computation.\n bool c = b.equals(a) || b.startsWith(a);\n\n // Join as a list.\n strings.slice memory delim = c ? string(\",\").toSlice() : string(\";\").toSlice();\n strings.slice[] memory parts = new strings.slice[](2);\n parts[0] = a;\n parts[1] = b;\n string memory d = delim.join(parts);\n return d.toSlice().len();\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 95303\n// gas irOptimized code: 520000\n// gas legacy: 126346\n// gas legacy code: 932600\n// gas legacyOptimized: 102639\n// gas legacyOptimized code: 612400\n// toSlice(string): 0x20, 11, \"hello world\" -> 11, 0xa0\n// gas irOptimized: 22660\n// gas legacy: 23190\n// gas legacyOptimized: 22508\n// roundtrip(string): 0x20, 11, \"hello world\" -> 0x20, 11, \"hello world\"\n// gas irOptimized: 23408\n// gas legacy: 23820\n// gas legacyOptimized: 23123\n// utf8len(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 4 # Input: \"\ud83d\ude03\ud83d\ude03\ud83d\ude03\ud83d\ude03\" #\n// gas irOptimized: 24026\n// gas legacy: 25716\n// gas legacyOptimized: 24115\n// multiconcat(string,uint256): 0x40, 3, 11, \"hello world\" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times #\n// gas irOptimized: 28440\n// gas legacy: 31621\n// gas legacyOptimized: 27914\n// benchmark(string,bytes32): 0x40, 0x0842021, 8, \"solidity\" -> 0x2020\n// gas irOptimized: 1976778\n// gas legacy: 4234020\n// gas legacyOptimized: 2318668\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__external_external/external.sol b/examples/test/semanticTests/externalSource__external_external/external.sol new file mode 100644 index 00000000..3289e6ec --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_external/external.sol @@ -0,0 +1,2 @@ +contract External { +} diff --git a/examples/test/semanticTests/externalSource__external_external/external_standard_input.json b/examples/test/semanticTests/externalSource__external_external/external_standard_input.json new file mode 100644 index 00000000..36cb0af3 --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_external/external_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "import \"external.sol\";\nimport \"other_external.sol\";\n" + }, + "external.sol": { + "content": "contract External {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__external_import/import.sol b/examples/test/semanticTests/externalSource__external_import/import.sol new file mode 100644 index 00000000..30915351 --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_import/import.sol @@ -0,0 +1,2 @@ +import "external.sol"; +import "other_external.sol"; diff --git a/examples/test/semanticTests/externalSource__external_import/import_standard_input.json b/examples/test/semanticTests/externalSource__external_import/import_standard_input.json new file mode 100644 index 00000000..9be773aa --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_import/import_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "import \"external.sol\";\nimport \"other_external.sol\";\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir.sol b/examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir.sol new file mode 100644 index 00000000..a8e23be5 --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir.sol @@ -0,0 +1 @@ +import "subdir/import.sol"; diff --git a/examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir_standard_input.json b/examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir_standard_input.json new file mode 100644 index 00000000..10f8399b --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_import_with_subdir/import_with_subdir_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "import \"external.sol\";\nimport \"other_external.sol\";\n" + }, + "external.sol": { + "content": "contract External {\n}\n" + }, + "other_external.sol": { + "content": "contract OtherExternal {\n}\n" + }, + "import_with_subdir.sol": { + "content": "import \"subdir/import.sol\";\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__external_other_external/other_external.sol b/examples/test/semanticTests/externalSource__external_other_external/other_external.sol new file mode 100644 index 00000000..7a686b3d --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_other_external/other_external.sol @@ -0,0 +1,2 @@ +contract OtherExternal { +} diff --git a/examples/test/semanticTests/externalSource__external_other_external/other_external_standard_input.json b/examples/test/semanticTests/externalSource__external_other_external/other_external_standard_input.json new file mode 100644 index 00000000..5cbdf5fe --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_other_external/other_external_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "import \"external.sol\";\nimport \"other_external.sol\";\n" + }, + "external.sol": { + "content": "contract External {\n}\n" + }, + "other_external.sol": { + "content": "contract OtherExternal {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__external_subdir_import/import.sol b/examples/test/semanticTests/externalSource__external_subdir_import/import.sol new file mode 100644 index 00000000..bf0ef42c --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_subdir_import/import.sol @@ -0,0 +1 @@ +import "sub_external.sol"; diff --git a/examples/test/semanticTests/externalSource__external_subdir_import/import_standard_input.json b/examples/test/semanticTests/externalSource__external_subdir_import/import_standard_input.json new file mode 100644 index 00000000..ccfabe3b --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_subdir_import/import_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "import \"sub_external.sol\";\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external.sol b/examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external.sol new file mode 100644 index 00000000..63a3bd18 --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external.sol @@ -0,0 +1,2 @@ +contract SubExternal { +} diff --git a/examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external_standard_input.json b/examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external_standard_input.json new file mode 100644 index 00000000..8541f719 --- /dev/null +++ b/examples/test/semanticTests/externalSource__external_subdir_sub_external/sub_external_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "import \"sub_external.sol\";\n" + }, + "sub_external.sol": { + "content": "contract SubExternal {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__non_normalized_paths_a/a.sol b/examples/test/semanticTests/externalSource__non_normalized_paths_a/a.sol new file mode 100644 index 00000000..4e829399 --- /dev/null +++ b/examples/test/semanticTests/externalSource__non_normalized_paths_a/a.sol @@ -0,0 +1,2 @@ +contract A { +} diff --git a/examples/test/semanticTests/externalSource__non_normalized_paths_a/a_standard_input.json b/examples/test/semanticTests/externalSource__non_normalized_paths_a/a_standard_input.json new file mode 100644 index 00000000..313d2bae --- /dev/null +++ b/examples/test/semanticTests/externalSource__non_normalized_paths_a/a_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "d.sol": { + "content": "contract D {\n}\n" + }, + "c.sol": { + "content": "contract C {\n}\n" + }, + "a.sol": { + "content": "contract A {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__non_normalized_paths_c/c.sol b/examples/test/semanticTests/externalSource__non_normalized_paths_c/c.sol new file mode 100644 index 00000000..41a6d567 --- /dev/null +++ b/examples/test/semanticTests/externalSource__non_normalized_paths_c/c.sol @@ -0,0 +1,2 @@ +contract C { +} diff --git a/examples/test/semanticTests/externalSource__non_normalized_paths_c/c_standard_input.json b/examples/test/semanticTests/externalSource__non_normalized_paths_c/c_standard_input.json new file mode 100644 index 00000000..fb5e4db5 --- /dev/null +++ b/examples/test/semanticTests/externalSource__non_normalized_paths_c/c_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "d.sol": { + "content": "contract D {\n}\n" + }, + "c.sol": { + "content": "contract C {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__non_normalized_paths_d/d.sol b/examples/test/semanticTests/externalSource__non_normalized_paths_d/d.sol new file mode 100644 index 00000000..0c9cba07 --- /dev/null +++ b/examples/test/semanticTests/externalSource__non_normalized_paths_d/d.sol @@ -0,0 +1,2 @@ +contract D { +} diff --git a/examples/test/semanticTests/externalSource__non_normalized_paths_d/d_standard_input.json b/examples/test/semanticTests/externalSource__non_normalized_paths_d/d_standard_input.json new file mode 100644 index 00000000..d8ab4d39 --- /dev/null +++ b/examples/test/semanticTests/externalSource__non_normalized_paths_d/d_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "d.sol": { + "content": "contract D {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_D_d/d.sol b/examples/test/semanticTests/externalSource__relative_imports_D_d/d.sol new file mode 100644 index 00000000..0c9cba07 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_D_d/d.sol @@ -0,0 +1,2 @@ +contract D { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_D_d/d_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_D_d/d_standard_input.json new file mode 100644 index 00000000..d8ab4d39 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_D_d/d_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "d.sol": { + "content": "contract D {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_c/c.sol b/examples/test/semanticTests/externalSource__relative_imports_c/c.sol new file mode 100644 index 00000000..41a6d567 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_c/c.sol @@ -0,0 +1,2 @@ +contract C { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_c/c_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_c/c_standard_input.json new file mode 100644 index 00000000..5570fbbe --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_c/c_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "h.sol": { + "content": "contract H {\n}\n" + }, + "c.sol": { + "content": "contract C {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b.sol b/examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b.sol new file mode 100644 index 00000000..5611e6fa --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b.sol @@ -0,0 +1,3 @@ +import {C} from "../../c.sol"; +contract B { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b_standard_input.json new file mode 100644 index 00000000..9a5abe70 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_B_b/b_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "b.sol": { + "content": "import {C} from \"../../c.sol\";\ncontract B {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g.sol b/examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g.sol new file mode 100644 index 00000000..1d2096de --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g.sol @@ -0,0 +1,3 @@ +import {B} from "../B/b.sol"; +contract G { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g_standard_input.json new file mode 100644 index 00000000..84a7f1ee --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_G_g/g_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "g.sol": { + "content": "import {B} from \"../B/b.sol\";\ncontract G {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_a/a.sol b/examples/test/semanticTests/externalSource__relative_imports_dir_a/a.sol new file mode 100644 index 00000000..4e829399 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_a/a.sol @@ -0,0 +1,2 @@ +contract A { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_a/a_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_dir_a/a_standard_input.json new file mode 100644 index 00000000..cad18ee6 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_a/a_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "contract.sol": { + "content": "import {A} from \"./a.sol\";\nimport {B} from \"./B/b.sol\";\nimport {C} from \"../c.sol\";\nimport {D} from \"../D/d.sol\";\nimport {G} from \"./E/../F/../G/./g.sol\";\nimport {H} from \"../../../../_relative_imports/h.sol\";\ncontract Contract {\n}\n" + }, + "a.sol": { + "content": "contract A {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract.sol b/examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract.sol new file mode 100644 index 00000000..aab81b97 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract.sol @@ -0,0 +1,8 @@ +import {A} from "./a.sol"; +import {B} from "./B/b.sol"; +import {C} from "../c.sol"; +import {D} from "../D/d.sol"; +import {G} from "./E/../F/../G/./g.sol"; +import {H} from "../../../../_relative_imports/h.sol"; +contract Contract { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract_standard_input.json new file mode 100644 index 00000000..40e6d576 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_dir_contract/contract_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "contract.sol": { + "content": "import {A} from \"./a.sol\";\nimport {B} from \"./B/b.sol\";\nimport {C} from \"../c.sol\";\nimport {D} from \"../D/d.sol\";\nimport {G} from \"./E/../F/../G/./g.sol\";\nimport {H} from \"../../../../_relative_imports/h.sol\";\ncontract Contract {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__relative_imports_h/h.sol b/examples/test/semanticTests/externalSource__relative_imports_h/h.sol new file mode 100644 index 00000000..2d969980 --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_h/h.sol @@ -0,0 +1,2 @@ +contract H { +} diff --git a/examples/test/semanticTests/externalSource__relative_imports_h/h_standard_input.json b/examples/test/semanticTests/externalSource__relative_imports_h/h_standard_input.json new file mode 100644 index 00000000..3b29919b --- /dev/null +++ b/examples/test/semanticTests/externalSource__relative_imports_h/h_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "h.sol": { + "content": "contract H {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b.sol b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b.sol new file mode 100644 index 00000000..8b4d6395 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b.sol @@ -0,0 +1,2 @@ +contract B { +} diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b_standard_input.json b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b_standard_input.json new file mode 100644 index 00000000..04ffcc67 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_b/b_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "dot_a.sol": { + "content": "contract Dot_A {\n}\n" + }, + "dot_dot_b.sol": { + "content": "contract Dot_Dot_B {\n}\n" + }, + "b.sol": { + "content": "contract B {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a.sol b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a.sol new file mode 100644 index 00000000..4e829399 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a.sol @@ -0,0 +1,2 @@ +contract A { +} diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a_standard_input.json b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a_standard_input.json new file mode 100644 index 00000000..1f89d422 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_a/a_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "contract.sol": { + "content": "import {A} from \"./a.sol\";\nimport {B} from \"../b.sol\";\n" + }, + "a.sol": { + "content": "contract A {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract.sol b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract.sol new file mode 100644 index 00000000..f67d9702 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract.sol @@ -0,0 +1,2 @@ +import {A} from "./a.sol"; +import {B} from "../b.sol"; diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract_standard_input.json b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract_standard_input.json new file mode 100644 index 00000000..2425eb1b --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dir_contract/contract_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "contract.sol": { + "content": "import {A} from \"./a.sol\";\nimport {B} from \"../b.sol\";\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a.sol b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a.sol new file mode 100644 index 00000000..3f155422 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a.sol @@ -0,0 +1,2 @@ +contract Dot_A { +} diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a_standard_input.json b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a_standard_input.json new file mode 100644 index 00000000..7f84abf6 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_a/dot_a_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "dot_a.sol": { + "content": "contract Dot_A {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b.sol b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b.sol new file mode 100644 index 00000000..037c8121 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b.sol @@ -0,0 +1,2 @@ +contract Dot_Dot_B { +} diff --git a/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b_standard_input.json b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b_standard_input.json new file mode 100644 index 00000000..fad9bad1 --- /dev/null +++ b/examples/test/semanticTests/externalSource__source_name_starting_with_dots_dot_dot_b/dot_dot_b_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "dot_a.sol": { + "content": "contract Dot_A {\n}\n" + }, + "dot_dot_b.sol": { + "content": "contract Dot_Dot_B {\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs.sol b/examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs.sol new file mode 100644 index 00000000..149109f6 --- /dev/null +++ b/examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs.sol @@ -0,0 +1,6 @@ +==== ExternalSource: a=_external/external.sol=sol ==== +import {External} from "a"; +contract C { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs_standard_input.json b/examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs_standard_input.json new file mode 100644 index 00000000..966ed120 --- /dev/null +++ b/examples/test/semanticTests/externalSource_multiple_equals_signs/multiple_equals_signs_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source.sol b/examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source.sol new file mode 100644 index 00000000..f16a7b0a --- /dev/null +++ b/examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source.sol @@ -0,0 +1,8 @@ +==== ExternalSource: _external/external.sol ==== +==== ExternalSource: _external/other_external.sol ==== +import {External} from "_external/external.sol"; +import {OtherExternal} from "_external/other_external.sol"; +contract C { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source_standard_input.json b/examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source_standard_input.json new file mode 100644 index 00000000..e43ffc94 --- /dev/null +++ b/examples/test/semanticTests/externalSource_multiple_external_source/multiple_external_source_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + }, + "multiple_external_source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_multisource/multisource.sol b/examples/test/semanticTests/externalSource_multisource/multisource.sol new file mode 100644 index 00000000..685f0b9d --- /dev/null +++ b/examples/test/semanticTests/externalSource_multisource/multisource.sol @@ -0,0 +1,12 @@ +==== ExternalSource: _external/external.sol ==== +==== Source: s1.sol ==== +import {External} from "_external/external.sol"; +contract S1 { +} +==== Source: s2.sol ==== +import {S1} from "s1.sol"; +contract C { +} +// ---- +// constructor() + diff --git a/examples/test/semanticTests/externalSource_multisource/multisource_standard_input.json b/examples/test/semanticTests/externalSource_multisource/multisource_standard_input.json new file mode 100644 index 00000000..cd636f8f --- /dev/null +++ b/examples/test/semanticTests/externalSource_multisource/multisource_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + }, + "multiple_external_source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import_subdir.sol": { + "content": "==== ExternalSource: _external/import_with_subdir.sol ====\n==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ====\n==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ====\nimport {SubExternal} from \"sub_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "non_normalized_paths.sol": { + "content": "==== ExternalSource: _non_normalized_paths//a.sol ====\n==== ExternalSource: C/////c.sol=_non_normalized_paths/c.sol ====\n==== ExternalSource: C/../////D/d.sol=_non_normalized_paths///d.sol ====\nimport {A} from \"_non_normalized_paths//a.sol\";\nimport {C} from \"C/////c.sol\";\nimport {D} from \"C/../////D/d.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n" + }, + "multisource.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== Source: s1.sol ====\nimport {External} from \"_external/external.sol\";\ncontract S1 {\n}\n==== Source: s2.sol ====\nimport {S1} from \"s1.sol\";\ncontract C {\n}\n// ----\n// constructor()\n\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths.sol b/examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths.sol new file mode 100644 index 00000000..7316cc7d --- /dev/null +++ b/examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths.sol @@ -0,0 +1,10 @@ +==== ExternalSource: _non_normalized_paths//a.sol ==== +==== ExternalSource: C/////c.sol=_non_normalized_paths/c.sol ==== +==== ExternalSource: C/../////D/d.sol=_non_normalized_paths///d.sol ==== +import {A} from "_non_normalized_paths//a.sol"; +import {C} from "C/////c.sol"; +import {D} from "C/../////D/d.sol"; +contract Contract { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths_standard_input.json b/examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths_standard_input.json new file mode 100644 index 00000000..88e11d5f --- /dev/null +++ b/examples/test/semanticTests/externalSource_non_normalized_paths/non_normalized_paths_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + }, + "multiple_external_source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import_subdir.sol": { + "content": "==== ExternalSource: _external/import_with_subdir.sol ====\n==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ====\n==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ====\nimport {SubExternal} from \"sub_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "non_normalized_paths.sol": { + "content": "==== ExternalSource: _non_normalized_paths//a.sol ====\n==== ExternalSource: C/////c.sol=_non_normalized_paths/c.sol ====\n==== ExternalSource: C/../////D/d.sol=_non_normalized_paths///d.sol ====\nimport {A} from \"_non_normalized_paths//a.sol\";\nimport {C} from \"C/////c.sol\";\nimport {D} from \"C/../////D/d.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_relative_imports/relative_imports.sol b/examples/test/semanticTests/externalSource_relative_imports/relative_imports.sol new file mode 100644 index 00000000..9a37896b --- /dev/null +++ b/examples/test/semanticTests/externalSource_relative_imports/relative_imports.sol @@ -0,0 +1,12 @@ +==== ExternalSource: _relative_imports/dir/contract.sol ==== +==== ExternalSource: _relative_imports/dir/a.sol ==== +==== ExternalSource: _relative_imports/dir/B/b.sol ==== +==== ExternalSource: _relative_imports/c.sol ==== +==== ExternalSource: _relative_imports/D/d.sol ==== +==== ExternalSource: _relative_imports/dir/G/g.sol ==== +==== ExternalSource: _relative_imports/h.sol ==== +import {A, B, C, D, G, H, Contract} from "_relative_imports/dir/contract.sol"; +contract CC { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_relative_imports/relative_imports_standard_input.json b/examples/test/semanticTests/externalSource_relative_imports/relative_imports_standard_input.json new file mode 100644 index 00000000..cd137049 --- /dev/null +++ b/examples/test/semanticTests/externalSource_relative_imports/relative_imports_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_source/source.sol b/examples/test/semanticTests/externalSource_source/source.sol new file mode 100644 index 00000000..12a50ff8 --- /dev/null +++ b/examples/test/semanticTests/externalSource_source/source.sol @@ -0,0 +1,6 @@ +==== ExternalSource: _external/external.sol ==== +import {External} from "_external/external.sol"; +contract C { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_source/source_standard_input.json b/examples/test/semanticTests/externalSource_source/source_standard_input.json new file mode 100644 index 00000000..9a67c413 --- /dev/null +++ b/examples/test/semanticTests/externalSource_source/source_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + }, + "multiple_external_source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import_subdir.sol": { + "content": "==== ExternalSource: _external/import_with_subdir.sol ====\n==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ====\n==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ====\nimport {SubExternal} from \"sub_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "non_normalized_paths.sol": { + "content": "==== ExternalSource: _non_normalized_paths//a.sol ====\n==== ExternalSource: C/////c.sol=_non_normalized_paths/c.sol ====\n==== ExternalSource: C/../////D/d.sol=_non_normalized_paths///d.sol ====\nimport {A} from \"_non_normalized_paths//a.sol\";\nimport {C} from \"C/////c.sol\";\nimport {D} from \"C/../////D/d.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n" + }, + "multisource.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== Source: s1.sol ====\nimport {External} from \"_external/external.sol\";\ncontract S1 {\n}\n==== Source: s2.sol ====\nimport {S1} from \"s1.sol\";\ncontract C {\n}\n// ----\n// constructor()\n\n" + }, + "source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\nimport {External} from \"_external/external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_source_import/source_import.sol b/examples/test/semanticTests/externalSource_source_import/source_import.sol new file mode 100644 index 00000000..f16a7b0a --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_import/source_import.sol @@ -0,0 +1,8 @@ +==== ExternalSource: _external/external.sol ==== +==== ExternalSource: _external/other_external.sol ==== +import {External} from "_external/external.sol"; +import {OtherExternal} from "_external/other_external.sol"; +contract C { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_source_import/source_import_standard_input.json b/examples/test/semanticTests/externalSource_source_import/source_import_standard_input.json new file mode 100644 index 00000000..66d1d32a --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_import/source_import_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir.sol b/examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir.sol new file mode 100644 index 00000000..35f3b5ba --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir.sol @@ -0,0 +1,8 @@ +==== ExternalSource: _external/import_with_subdir.sol ==== +==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ==== +==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ==== +import {SubExternal} from "sub_external.sol"; +contract C { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir_standard_input.json b/examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir_standard_input.json new file mode 100644 index 00000000..de48c1b6 --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_import_subdir/source_import_subdir_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + }, + "multiple_external_source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import_subdir.sol": { + "content": "==== ExternalSource: _external/import_with_subdir.sol ====\n==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ====\n==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ====\nimport {SubExternal} from \"sub_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots.sol b/examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots.sol new file mode 100644 index 00000000..b671c94f --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots.sol @@ -0,0 +1,10 @@ +==== ExternalSource: ./a.sol=_source_name_starting_with_dots/dot_a.sol ==== +==== ExternalSource: ../b.sol=_source_name_starting_with_dots/dot_dot_b.sol ==== +==== ExternalSource: _source_name_starting_with_dots/dir/a.sol ==== +==== ExternalSource: _source_name_starting_with_dots/b.sol ==== +==== ExternalSource: _source_name_starting_with_dots/dir/contract.sol ==== +import {A, B} from "_source_name_starting_with_dots/dir/contract.sol"; +contract Contract { +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots_standard_input.json b/examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots_standard_input.json new file mode 100644 index 00000000..cf011a9e --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_name_starting_with_dots/source_name_starting_with_dots_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + }, + "multiple_external_source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import_subdir.sol": { + "content": "==== ExternalSource: _external/import_with_subdir.sol ====\n==== ExternalSource: subdir/import.sol=_external/subdir/import.sol ====\n==== ExternalSource: sub_external.sol=_external/subdir/sub_external.sol ====\nimport {SubExternal} from \"sub_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "non_normalized_paths.sol": { + "content": "==== ExternalSource: _non_normalized_paths//a.sol ====\n==== ExternalSource: C/////c.sol=_non_normalized_paths/c.sol ====\n==== ExternalSource: C/../////D/d.sol=_non_normalized_paths///d.sol ====\nimport {A} from \"_non_normalized_paths//a.sol\";\nimport {C} from \"C/////c.sol\";\nimport {D} from \"C/../////D/d.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n" + }, + "multisource.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== Source: s1.sol ====\nimport {External} from \"_external/external.sol\";\ncontract S1 {\n}\n==== Source: s2.sol ====\nimport {S1} from \"s1.sol\";\ncontract C {\n}\n// ----\n// constructor()\n\n" + }, + "source.sol": { + "content": "==== ExternalSource: _external/external.sol ====\nimport {External} from \"_external/external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_name_starting_with_dots.sol": { + "content": "==== ExternalSource: ./a.sol=_source_name_starting_with_dots/dot_a.sol ====\n==== ExternalSource: ../b.sol=_source_name_starting_with_dots/dot_dot_b.sol ====\n==== ExternalSource: _source_name_starting_with_dots/dir/a.sol ====\n==== ExternalSource: _source_name_starting_with_dots/b.sol ====\n==== ExternalSource: _source_name_starting_with_dots/dir/contract.sol ====\nimport {A, B} from \"_source_name_starting_with_dots/dir/contract.sol\";\ncontract Contract {\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/externalSource_source_remapping/source_remapping.sol b/examples/test/semanticTests/externalSource_source_remapping/source_remapping.sol new file mode 100644 index 00000000..079a222f --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_remapping/source_remapping.sol @@ -0,0 +1,10 @@ +==== ExternalSource: ExtSource.sol=_external/external.sol ==== +==== ExternalSource: /ExtSource.sol=_external/other_external.sol ==== +import "ExtSource.sol"; +import "/ExtSource.sol"; +contract C { + External _external; + OtherExternal _otherExternal; +} +// ---- +// constructor() diff --git a/examples/test/semanticTests/externalSource_source_remapping/source_remapping_standard_input.json b/examples/test/semanticTests/externalSource_source_remapping/source_remapping_standard_input.json new file mode 100644 index 00000000..e5cd5e8a --- /dev/null +++ b/examples/test/semanticTests/externalSource_source_remapping/source_remapping_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "multiple_equals_signs.sol": { + "content": "==== ExternalSource: a=_external/external.sol=sol ====\nimport {External} from \"a\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "source_import.sol": { + "content": "==== ExternalSource: _external/external.sol ====\n==== ExternalSource: _external/other_external.sol ====\nimport {External} from \"_external/external.sol\";\nimport {OtherExternal} from \"_external/other_external.sol\";\ncontract C {\n}\n// ----\n// constructor()\n" + }, + "relative_imports.sol": { + "content": "==== ExternalSource: _relative_imports/dir/contract.sol ====\n==== ExternalSource: _relative_imports/dir/a.sol ====\n==== ExternalSource: _relative_imports/dir/B/b.sol ====\n==== ExternalSource: _relative_imports/c.sol ====\n==== ExternalSource: _relative_imports/D/d.sol ====\n==== ExternalSource: _relative_imports/dir/G/g.sol ====\n==== ExternalSource: _relative_imports/h.sol ====\nimport {A, B, C, D, G, H, Contract} from \"_relative_imports/dir/contract.sol\";\ncontract CC {\n}\n// ----\n// constructor()\n" + }, + "source_remapping.sol": { + "content": "==== ExternalSource: ExtSource.sol=_external/external.sol ====\n==== ExternalSource: /ExtSource.sol=_external/other_external.sol ====\nimport \"ExtSource.sol\";\nimport \"/ExtSource.sol\";\ncontract C {\n External _external;\n OtherExternal _otherExternal;\n}\n// ----\n// constructor()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes.sol b/examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes.sol new file mode 100644 index 00000000..7bf3aee3 --- /dev/null +++ b/examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes.sol @@ -0,0 +1,25 @@ +contract receiver { + uint256 public received; + function recv(uint256 x) public { received += x + 1; } + fallback() external { received = 0x80; } +} +contract sender { + constructor() { rec = new receiver();} + fallback() external { savedData = msg.data; } + function forward() public returns (bool) { address(rec).call(savedData); return true; } + function clear() public returns (bool) { delete savedData; return true; } + function val() public returns (uint) { return rec.received(); } + receiver rec; + bytes savedData; +} +// ==== +// allowNonExistingFunctions: true +// ---- +// recv(uint256): 7 -> +// val() -> 0 +// forward() -> true +// val() -> 8 +// clear() -> true +// val() -> 8 +// forward() -> true +// val() -> 0x80 diff --git a/examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes_standard_input.json b/examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes_standard_input.json new file mode 100644 index 00000000..e5efe0b9 --- /dev/null +++ b/examples/test/semanticTests/fallback_call_forward_bytes/call_forward_bytes_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + }, + "fallback_override2.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback () override external {\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n" + }, + "fallback_argument_to_storage.sol": { + "content": "contract A {\n bytes public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 0x20, 3, \"abc\"\n" + }, + "fallback_override_multi.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return \"xyz\";\n }\n}\ncontract C is B, A {\n fallback () external override (B, A) {}\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n" + }, + "call_forward_bytes.sol": { + "content": "contract receiver {\n uint256 public received;\n function recv(uint256 x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver();}\n fallback() external { savedData = msg.data; }\n function forward() public returns (bool) { address(rec).call(savedData); return true; }\n function clear() public returns (bool) { delete savedData; return true; }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// recv(uint256): 7 ->\n// val() -> 0\n// forward() -> true\n// val() -> 8\n// clear() -> true\n// val() -> 8\n// forward() -> true\n// val() -> 0x80\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_falback_return/falback_return.sol b/examples/test/semanticTests/fallback_falback_return/falback_return.sol new file mode 100644 index 00000000..d59bb9d4 --- /dev/null +++ b/examples/test/semanticTests/fallback_falback_return/falback_return.sol @@ -0,0 +1,16 @@ +contract A { + uint public x; + fallback () external { + if (x == 2) return; + x++; + } +} +// ---- +// () +// x() -> 1 +// () +// x() -> 2 +// () +// x() -> 2 +// () +// x() -> 2 diff --git a/examples/test/semanticTests/fallback_falback_return/falback_return_standard_input.json b/examples/test/semanticTests/fallback_falback_return/falback_return_standard_input.json new file mode 100644 index 00000000..445346d8 --- /dev/null +++ b/examples/test/semanticTests/fallback_falback_return/falback_return_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_argument/fallback_argument.sol b/examples/test/semanticTests/fallback_fallback_argument/fallback_argument.sol new file mode 100644 index 00000000..d3517207 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_argument/fallback_argument.sol @@ -0,0 +1,16 @@ +contract A { + uint public x; + fallback (bytes calldata _input) external returns (bytes memory) { + x = _input.length; + return ""; + } + function f() public returns (bool, bytes memory) { + (bool success, bytes memory retval) = address(this).call("abc"); + return (success, retval); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x01, 0x40, 0x00 +// x() -> 3 diff --git a/examples/test/semanticTests/fallback_fallback_argument/fallback_argument_standard_input.json b/examples/test/semanticTests/fallback_fallback_argument/fallback_argument_standard_input.json new file mode 100644 index 00000000..250d4254 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_argument/fallback_argument_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage.sol b/examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage.sol new file mode 100644 index 00000000..1a995a8c --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage.sol @@ -0,0 +1,16 @@ +contract A { + bytes public x; + fallback (bytes calldata _input) external returns (bytes memory) { + x = _input; + return ""; + } + function f() public returns (bool, bytes memory) { + (bool success, bytes memory retval) = address(this).call("abc"); + return (success, retval); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x01, 0x40, 0x00 +// x() -> 0x20, 3, "abc" diff --git a/examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage_standard_input.json b/examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage_standard_input.json new file mode 100644 index 00000000..fb434963 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_argument_to_storage/fallback_argument_to_storage_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + }, + "fallback_override2.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback () override external {\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n" + }, + "fallback_argument_to_storage.sol": { + "content": "contract A {\n bytes public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 0x20, 3, \"abc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive.sol b/examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive.sol new file mode 100644 index 00000000..9b5319ae --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive.sol @@ -0,0 +1,17 @@ +contract C { + uint x; + uint y; + fallback () payable external { ++x; } + receive () payable external { ++y; } + function f() external returns (uint, uint) { return (x, y); } +} +// ---- +// f() -> 0, 0 +// () -> +// f() -> 0, 1 +// (), 1 ether -> +// f() -> 0, 2 +// (): 1 -> +// f() -> 1, 2 +// (), 1 ether: 1 -> +// f() -> 2, 2 diff --git a/examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive_standard_input.json b/examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive_standard_input.json new file mode 100644 index 00000000..afce9560 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_or_receive/fallback_or_receive_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_override/fallback_override.sol b/examples/test/semanticTests/fallback_fallback_override/fallback_override.sol new file mode 100644 index 00000000..5e5adb37 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_override/fallback_override.sol @@ -0,0 +1,18 @@ +contract A { + fallback (bytes calldata _input) virtual external returns (bytes memory) { + return _input; + } +} +contract B is A { + fallback (bytes calldata _input) override external returns (bytes memory) { + return "xyz"; + } + function f() public returns (bool, bytes memory) { + (bool success, bytes memory retval) = address(this).call("abc"); + return (success, retval); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/fallback_fallback_override/fallback_override_standard_input.json b/examples/test/semanticTests/fallback_fallback_override/fallback_override_standard_input.json new file mode 100644 index 00000000..98e3069c --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_override/fallback_override_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_override2/fallback_override2.sol b/examples/test/semanticTests/fallback_fallback_override2/fallback_override2.sol new file mode 100644 index 00000000..67925fd5 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_override2/fallback_override2.sol @@ -0,0 +1,17 @@ +contract A { + fallback (bytes calldata _input) virtual external returns (bytes memory) { + return _input; + } +} +contract B is A { + fallback () override external { + } + function f() public returns (bool, bytes memory) { + (bool success, bytes memory retval) = address(this).call("abc"); + return (success, retval); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 1, 0x40, 0x00 diff --git a/examples/test/semanticTests/fallback_fallback_override2/fallback_override2_standard_input.json b/examples/test/semanticTests/fallback_fallback_override2/fallback_override2_standard_input.json new file mode 100644 index 00000000..fa4592cf --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_override2/fallback_override2_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + }, + "fallback_override2.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback () override external {\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi.sol b/examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi.sol new file mode 100644 index 00000000..ce268e4f --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi.sol @@ -0,0 +1,21 @@ +contract A { + fallback (bytes calldata _input) virtual external returns (bytes memory) { + return _input; + } +} +contract B { + fallback (bytes calldata _input) virtual external returns (bytes memory) { + return "xyz"; + } +} +contract C is B, A { + fallback () external override (B, A) {} + function f() public returns (bool, bytes memory) { + (bool success, bytes memory retval) = address(this).call("abc"); + return (success, retval); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x01, 0x40, 0x00 diff --git a/examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi_standard_input.json b/examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi_standard_input.json new file mode 100644 index 00000000..997ab880 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_override_multi/fallback_override_multi_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + }, + "fallback_override2.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback () override external {\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n" + }, + "fallback_argument_to_storage.sol": { + "content": "contract A {\n bytes public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 0x20, 3, \"abc\"\n" + }, + "fallback_override_multi.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return \"xyz\";\n }\n}\ncontract C is B, A {\n fallback () external override (B, A) {}\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data.sol b/examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data.sol new file mode 100644 index 00000000..d22c11e7 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data.sol @@ -0,0 +1,13 @@ +contract A { + fallback (bytes calldata _input) external returns (bytes memory) { + return _input; + } + function f() public returns (bool, bytes memory) { + (bool success, bytes memory retval) = address(this).call("abc"); + return (success, retval); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data_standard_input.json b/examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data_standard_input.json new file mode 100644 index 00000000..ad51fcf6 --- /dev/null +++ b/examples/test/semanticTests/fallback_fallback_return_data/fallback_return_data_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_inherited/inherited.sol b/examples/test/semanticTests/fallback_inherited/inherited.sol new file mode 100644 index 00000000..55c63944 --- /dev/null +++ b/examples/test/semanticTests/fallback_inherited/inherited.sol @@ -0,0 +1,10 @@ +contract A { + uint data; + fallback() external { data = 1; } + function getData() public returns (uint r) { return data; } +} +contract B is A {} +// ---- +// getData() -> 0 +// (): 42 -> +// getData() -> 1 diff --git a/examples/test/semanticTests/fallback_inherited/inherited_standard_input.json b/examples/test/semanticTests/fallback_inherited/inherited_standard_input.json new file mode 100644 index 00000000..9de92853 --- /dev/null +++ b/examples/test/semanticTests/fallback_inherited/inherited_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + }, + "fallback_override2.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback () override external {\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n" + }, + "fallback_argument_to_storage.sol": { + "content": "contract A {\n bytes public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 0x20, 3, \"abc\"\n" + }, + "fallback_override_multi.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return \"xyz\";\n }\n}\ncontract C is B, A {\n fallback () external override (B, A) {}\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n" + }, + "call_forward_bytes.sol": { + "content": "contract receiver {\n uint256 public received;\n function recv(uint256 x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver();}\n fallback() external { savedData = msg.data; }\n function forward() public returns (bool) { address(rec).call(savedData); return true; }\n function clear() public returns (bool) { delete savedData; return true; }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// recv(uint256): 7 ->\n// val() -> 0\n// forward() -> true\n// val() -> 8\n// clear() -> true\n// val() -> 8\n// forward() -> true\n// val() -> 0x80\n" + }, + "inherited.sol": { + "content": "contract A {\n uint data;\n fallback() external { data = 1; }\n function getData() public returns (uint r) { return data; }\n}\ncontract B is A {}\n// ----\n// getData() -> 0\n// (): 42 ->\n// getData() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback.sol b/examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback.sol new file mode 100644 index 00000000..dd97f4c0 --- /dev/null +++ b/examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback.sol @@ -0,0 +1,17 @@ +contract A { + uint public x; + // Signature is d88e0b00 + function fow() public { x = 3; } + fallback () external { x = 2; } +} +// ---- +// (): hex"d88e0b" +// x() -> 2 +// (): hex"d88e0b00" +// x() -> 3 +// (): hex"d88e" +// x() -> 2 +// (): hex"d88e0b00" +// x() -> 3 +// (): hex"d8" +// x() -> 2 diff --git a/examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback_standard_input.json b/examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback_standard_input.json new file mode 100644 index 00000000..850e3368 --- /dev/null +++ b/examples/test/semanticTests/fallback_short_data_calls_fallback/short_data_calls_fallback_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "fallback_argument.sol": { + "content": "contract A {\n uint public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input.length;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 3\n" + }, + "fallback_override.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback (bytes calldata _input) override external returns (bytes memory) {\n return \"xyz\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x78797a0000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_return_data.sol": { + "content": "contract A {\n fallback (bytes calldata _input) external returns (bytes memory) {\n return _input;\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "fallback_or_receive.sol": { + "content": "contract C {\n uint x;\n uint y;\n fallback () payable external { ++x; }\n receive () payable external { ++y; }\n function f() external returns (uint, uint) { return (x, y); }\n}\n// ----\n// f() -> 0, 0\n// () ->\n// f() -> 0, 1\n// (), 1 ether ->\n// f() -> 0, 2\n// (): 1 ->\n// f() -> 1, 2\n// (), 1 ether: 1 ->\n// f() -> 2, 2\n" + }, + "falback_return.sol": { + "content": "contract A {\n uint public x;\n fallback () external {\n if (x == 2) return;\n x++;\n }\n}\n// ----\n// ()\n// x() -> 1\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n// ()\n// x() -> 2\n" + }, + "fallback_override2.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B is A {\n fallback () override external {\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 1, 0x40, 0x00\n" + }, + "fallback_argument_to_storage.sol": { + "content": "contract A {\n bytes public x;\n fallback (bytes calldata _input) external returns (bytes memory) {\n x = _input;\n return \"\";\n }\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n// x() -> 0x20, 3, \"abc\"\n" + }, + "fallback_override_multi.sol": { + "content": "contract A {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return _input;\n }\n}\ncontract B {\n fallback (bytes calldata _input) virtual external returns (bytes memory) {\n return \"xyz\";\n }\n}\ncontract C is B, A {\n fallback () external override (B, A) {}\n function f() public returns (bool, bytes memory) {\n (bool success, bytes memory retval) = address(this).call(\"abc\");\n return (success, retval);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x01, 0x40, 0x00\n" + }, + "call_forward_bytes.sol": { + "content": "contract receiver {\n uint256 public received;\n function recv(uint256 x) public { received += x + 1; }\n fallback() external { received = 0x80; }\n}\ncontract sender {\n constructor() { rec = new receiver();}\n fallback() external { savedData = msg.data; }\n function forward() public returns (bool) { address(rec).call(savedData); return true; }\n function clear() public returns (bool) { delete savedData; return true; }\n function val() public returns (uint) { return rec.received(); }\n receiver rec;\n bytes savedData;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// recv(uint256): 7 ->\n// val() -> 0\n// forward() -> true\n// val() -> 8\n// clear() -> true\n// val() -> 8\n// forward() -> true\n// val() -> 0x80\n" + }, + "inherited.sol": { + "content": "contract A {\n uint data;\n fallback() external { data = 1; }\n function getData() public returns (uint r) { return data; }\n}\ncontract B is A {}\n// ----\n// getData() -> 0\n// (): 42 ->\n// getData() -> 1\n" + }, + "short_data_calls_fallback.sol": { + "content": "contract A {\n uint public x;\n // Signature is d88e0b00\n function fow() public { x = 3; }\n fallback () external { x = 2; }\n}\n// ----\n// (): hex\"d88e0b\"\n// x() -> 2\n// (): hex\"d88e0b00\"\n// x() -> 3\n// (): hex\"d88e\"\n// x() -> 2\n// (): hex\"d88e0b00\"\n// x() -> 3\n// (): hex\"d8\"\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_easy/easy.sol b/examples/test/semanticTests/freeFunctions_easy/easy.sol new file mode 100644 index 00000000..f73f1012 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_easy/easy.sol @@ -0,0 +1,11 @@ +function add(uint a, uint b) pure returns (uint) { + return a + b; +} + +contract C { + function f(uint x) public pure returns (uint) { + return add(x, 2); + } +} +// ---- +// f(uint256): 7 -> 9 diff --git a/examples/test/semanticTests/freeFunctions_easy/easy_standard_input.json b/examples/test/semanticTests/freeFunctions_easy/easy_standard_input.json new file mode 100644 index 00000000..09d112e3 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_easy/easy_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + }, + "libraries_from_free.sol": { + "content": "library L {\n function pub() public pure returns (uint) {\n return 7;\n }\n function inter() internal pure returns (uint) {\n return 8;\n }\n}\n\nfunction fu() pure returns (uint, uint) {\n return (L.pub(), L.inter());\n}\n\ncontract C {\n function f() public pure returns (uint, uint) {\n return fu();\n }\n}\n// ----\n// library: L\n// f() -> 7, 8\n" + }, + "easy.sol": { + "content": "function add(uint a, uint b) pure returns (uint) {\n return a + b;\n}\n\ncontract C {\n function f(uint x) public pure returns (uint) {\n return add(x, 2);\n }\n}\n// ----\n// f(uint256): 7 -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function.sol b/examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function.sol new file mode 100644 index 00000000..cf414028 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function.sol @@ -0,0 +1,8 @@ +function f() pure returns (uint) { return 1337; } +contract C { + function f() public pure returns (uint) { + return f(); + } +} +// ---- +// f() -> FAILURE diff --git a/examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function_standard_input.json b/examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function_standard_input.json new file mode 100644 index 00000000..276dfe85 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_free_namesake_contract_function/free_namesake_contract_function_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + }, + "libraries_from_free.sol": { + "content": "library L {\n function pub() public pure returns (uint) {\n return 7;\n }\n function inter() internal pure returns (uint) {\n return 8;\n }\n}\n\nfunction fu() pure returns (uint, uint) {\n return (L.pub(), L.inter());\n}\n\ncontract C {\n function f() public pure returns (uint, uint) {\n return fu();\n }\n}\n// ----\n// library: L\n// f() -> 7, 8\n" + }, + "easy.sol": { + "content": "function add(uint a, uint b) pure returns (uint) {\n return a + b;\n}\n\ncontract C {\n function f(uint x) public pure returns (uint) {\n return add(x, 2);\n }\n}\n// ----\n// f(uint256): 7 -> 9\n" + }, + "new_operator.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (uint) {\n return (new C()).x();\n}\n\ncontract D {\n function f() public returns (uint) {\n return test();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76611\n// gas legacy code: 23600\n" + }, + "free_namesake_contract_function.sol": { + "content": "function f() pure returns (uint) { return 1337; }\ncontract C {\n function f() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// f() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode.sol b/examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode.sol new file mode 100644 index 00000000..7a05ff5d --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode.sol @@ -0,0 +1,15 @@ +contract C { + uint public x = 2; +} + +function test() returns (bool) { + return type(C).runtimeCode.length > 20; +} + +contract D { + function f() public returns (bool) { + return test(); + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode_standard_input.json b/examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode_standard_input.json new file mode 100644 index 00000000..208d0455 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_free_runtimecode/free_runtimecode_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_import/import.sol b/examples/test/semanticTests/freeFunctions_import/import.sol new file mode 100644 index 00000000..edd44de4 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_import/import.sol @@ -0,0 +1,18 @@ +==== Source: A ==== +struct S { uint x; } +function set(S storage a, uint v) { a.x = v; } + +==== Source: B ==== +import "A"; +import "A" as A; +contract C { + A.S data; + function f(uint v) public returns (uint one, uint two) { + A.set(data, v); + one = data.x; + set(data, v + 1); + two = data.x; + } +} +// ---- +// f(uint256): 7 -> 7, 8 diff --git a/examples/test/semanticTests/freeFunctions_import/import_standard_input.json b/examples/test/semanticTests/freeFunctions_import/import_standard_input.json new file mode 100644 index 00000000..9cbe3a1e --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_import/import_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free.sol b/examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free.sol new file mode 100644 index 00000000..f7d2cf20 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free.sol @@ -0,0 +1,21 @@ +library L { + function pub() public pure returns (uint) { + return 7; + } + function inter() internal pure returns (uint) { + return 8; + } +} + +function fu() pure returns (uint, uint) { + return (L.pub(), L.inter()); +} + +contract C { + function f() public pure returns (uint, uint) { + return fu(); + } +} +// ---- +// library: L +// f() -> 7, 8 diff --git a/examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free_standard_input.json b/examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free_standard_input.json new file mode 100644 index 00000000..e81e4bdd --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_libraries_from_free/libraries_from_free_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + }, + "libraries_from_free.sol": { + "content": "library L {\n function pub() public pure returns (uint) {\n return 7;\n }\n function inter() internal pure returns (uint) {\n return 8;\n }\n}\n\nfunction fu() pure returns (uint, uint) {\n return (L.pub(), L.inter());\n}\n\ncontract C {\n function f() public pure returns (uint, uint) {\n return fu();\n }\n}\n// ----\n// library: L\n// f() -> 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_new_operator/new_operator.sol b/examples/test/semanticTests/freeFunctions_new_operator/new_operator.sol new file mode 100644 index 00000000..d621629c --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_new_operator/new_operator.sol @@ -0,0 +1,17 @@ +contract C { + uint public x = 2; +} + +function test() returns (uint) { + return (new C()).x(); +} + +contract D { + function f() public returns (uint) { + return test(); + } +} +// ---- +// f() -> 2 +// gas legacy: 76611 +// gas legacy code: 23600 diff --git a/examples/test/semanticTests/freeFunctions_new_operator/new_operator_standard_input.json b/examples/test/semanticTests/freeFunctions_new_operator/new_operator_standard_input.json new file mode 100644 index 00000000..dc3c0831 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_new_operator/new_operator_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + }, + "libraries_from_free.sol": { + "content": "library L {\n function pub() public pure returns (uint) {\n return 7;\n }\n function inter() internal pure returns (uint) {\n return 8;\n }\n}\n\nfunction fu() pure returns (uint, uint) {\n return (L.pub(), L.inter());\n}\n\ncontract C {\n function f() public pure returns (uint, uint) {\n return fu();\n }\n}\n// ----\n// library: L\n// f() -> 7, 8\n" + }, + "easy.sol": { + "content": "function add(uint a, uint b) pure returns (uint) {\n return a + b;\n}\n\ncontract C {\n function f(uint x) public pure returns (uint) {\n return add(x, 2);\n }\n}\n// ----\n// f(uint256): 7 -> 9\n" + }, + "new_operator.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (uint) {\n return (new C()).x();\n}\n\ncontract D {\n function f() public returns (uint) {\n return test();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76611\n// gas legacy code: 23600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_overloads/overloads.sol b/examples/test/semanticTests/freeFunctions_overloads/overloads.sol new file mode 100644 index 00000000..6a2da653 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_overloads/overloads.sol @@ -0,0 +1,14 @@ +function f(uint) returns (uint) { + return 2; +} +function f(string memory) returns (uint) { + return 3; +} + +contract C { + function g() public returns (uint, uint) { + return (f(2), f("abc")); + } +} +// ---- +// g() -> 2, 3 diff --git a/examples/test/semanticTests/freeFunctions_overloads/overloads_standard_input.json b/examples/test/semanticTests/freeFunctions_overloads/overloads_standard_input.json new file mode 100644 index 00000000..cd8748af --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_overloads/overloads_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_recursion/recursion.sol b/examples/test/semanticTests/freeFunctions_recursion/recursion.sol new file mode 100644 index 00000000..894a60f3 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_recursion/recursion.sol @@ -0,0 +1,21 @@ +function exp(uint base, uint exponent) pure returns (uint power) { + if (exponent == 0) + return 1; + power = exp(base, exponent / 2); + power *= power; + if (exponent & 1 == 1) + power *= base; +} + +contract C { + function g(uint base, uint exponent) public pure returns (uint) { + return exp(base, exponent); + } +} +// ---- +// g(uint256,uint256): 0, 0 -> 1 +// g(uint256,uint256): 0, 1 -> 0x00 +// g(uint256,uint256): 1, 0 -> 1 +// g(uint256,uint256): 2, 3 -> 8 +// g(uint256,uint256): 3, 10 -> 59049 +// g(uint256,uint256): 2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 diff --git a/examples/test/semanticTests/freeFunctions_recursion/recursion_standard_input.json b/examples/test/semanticTests/freeFunctions_recursion/recursion_standard_input.json new file mode 100644 index 00000000..62dc08d7 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_recursion/recursion_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + }, + "libraries_from_free.sol": { + "content": "library L {\n function pub() public pure returns (uint) {\n return 7;\n }\n function inter() internal pure returns (uint) {\n return 8;\n }\n}\n\nfunction fu() pure returns (uint, uint) {\n return (L.pub(), L.inter());\n}\n\ncontract C {\n function f() public pure returns (uint, uint) {\n return fu();\n }\n}\n// ----\n// library: L\n// f() -> 7, 8\n" + }, + "easy.sol": { + "content": "function add(uint a, uint b) pure returns (uint) {\n return a + b;\n}\n\ncontract C {\n function f(uint x) public pure returns (uint) {\n return add(x, 2);\n }\n}\n// ----\n// f(uint256): 7 -> 9\n" + }, + "new_operator.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (uint) {\n return (new C()).x();\n}\n\ncontract D {\n function f() public returns (uint) {\n return test();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76611\n// gas legacy code: 23600\n" + }, + "free_namesake_contract_function.sol": { + "content": "function f() pure returns (uint) { return 1337; }\ncontract C {\n function f() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// f() -> FAILURE\n" + }, + "recursion.sol": { + "content": "function exp(uint base, uint exponent) pure returns (uint power) {\n if (exponent == 0)\n return 1;\n power = exp(base, exponent / 2);\n power *= power;\n if (exponent & 1 == 1)\n power *= base;\n}\n\ncontract C {\n function g(uint base, uint exponent) public pure returns (uint) {\n return exp(base, exponent);\n }\n}\n// ----\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 10 -> 59049\n// g(uint256,uint256): 2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs.sol b/examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs.sol new file mode 100644 index 00000000..3633fa95 --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs.sol @@ -0,0 +1,15 @@ +contract C { + uint[] data; + function f(uint x, uint[] calldata input) public returns (uint, uint) { + data.push(x); + (uint a, uint[] calldata b) = fun(input, data); + return (a, b[1]); + + } +} + +function fun(uint[] calldata _x, uint[] storage _y) view returns (uint, uint[] calldata) { + return (_y[0], _x); +} +// ---- +// f(uint256,uint256[]): 7, 0x40, 3, 8, 9, 10 -> 7, 9 diff --git a/examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs_standard_input.json b/examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs_standard_input.json new file mode 100644 index 00000000..47b1b34a --- /dev/null +++ b/examples/test/semanticTests/freeFunctions_storage_calldata_refs/storage_calldata_refs_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "import.sol": { + "content": "==== Source: A ====\nstruct S { uint x; }\nfunction set(S storage a, uint v) { a.x = v; }\n\n==== Source: B ====\nimport \"A\";\nimport \"A\" as A;\ncontract C {\n A.S data;\n function f(uint v) public returns (uint one, uint two) {\n A.set(data, v);\n one = data.x;\n set(data, v + 1);\n two = data.x;\n }\n}\n// ----\n// f(uint256): 7 -> 7, 8\n" + }, + "free_runtimecode.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (bool) {\n return type(C).runtimeCode.length > 20;\n}\n\ncontract D {\n function f() public returns (bool) {\n return test();\n }\n}\n// ----\n// f() -> true\n" + }, + "overloads.sol": { + "content": "function f(uint) returns (uint) {\n return 2;\n}\nfunction f(string memory) returns (uint) {\n return 3;\n}\n\ncontract C {\n function g() public returns (uint, uint) {\n return (f(2), f(\"abc\"));\n }\n}\n// ----\n// g() -> 2, 3\n" + }, + "libraries_from_free.sol": { + "content": "library L {\n function pub() public pure returns (uint) {\n return 7;\n }\n function inter() internal pure returns (uint) {\n return 8;\n }\n}\n\nfunction fu() pure returns (uint, uint) {\n return (L.pub(), L.inter());\n}\n\ncontract C {\n function f() public pure returns (uint, uint) {\n return fu();\n }\n}\n// ----\n// library: L\n// f() -> 7, 8\n" + }, + "easy.sol": { + "content": "function add(uint a, uint b) pure returns (uint) {\n return a + b;\n}\n\ncontract C {\n function f(uint x) public pure returns (uint) {\n return add(x, 2);\n }\n}\n// ----\n// f(uint256): 7 -> 9\n" + }, + "new_operator.sol": { + "content": "contract C {\n uint public x = 2;\n}\n\nfunction test() returns (uint) {\n return (new C()).x();\n}\n\ncontract D {\n function f() public returns (uint) {\n return test();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76611\n// gas legacy code: 23600\n" + }, + "free_namesake_contract_function.sol": { + "content": "function f() pure returns (uint) { return 1337; }\ncontract C {\n function f() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// f() -> FAILURE\n" + }, + "recursion.sol": { + "content": "function exp(uint base, uint exponent) pure returns (uint power) {\n if (exponent == 0)\n return 1;\n power = exp(base, exponent / 2);\n power *= power;\n if (exponent & 1 == 1)\n power *= base;\n}\n\ncontract C {\n function g(uint base, uint exponent) public pure returns (uint) {\n return exp(base, exponent);\n }\n}\n// ----\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 10 -> 59049\n// g(uint256,uint256): 2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + }, + "storage_calldata_refs.sol": { + "content": "contract C {\n uint[] data;\n function f(uint x, uint[] calldata input) public returns (uint, uint) {\n data.push(x);\n (uint a, uint[] calldata b) = fun(input, data);\n return (a, b[1]);\n\n }\n}\n\nfunction fun(uint[] calldata _x, uint[] storage _y) view returns (uint, uint[] calldata) {\n\treturn (_y[0], _x);\n}\n// ----\n// f(uint256,uint256[]): 7, 0x40, 3, 8, 9, 10 -> 7, 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars.sol b/examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars.sol new file mode 100644 index 00000000..4dbfe91f --- /dev/null +++ b/examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars.sol @@ -0,0 +1,28 @@ +contract test { + function f(uint256[] calldata seq) external pure returns (uint256) { + uint i = 0; + uint sum = 0; + while (i < seq.length) + { + uint idx = i; + if (idx >= 10) break; + uint x = seq[idx]; + if (x >= 1000) { + uint n = i + 1; + i = n; + continue; + } + else { + uint y = sum + x; + sum = y; + } + if (sum >= 500) return sum; + i++; + } + return sum; + } +} +// ---- +// f(uint256[]): 32, 3, 1000, 1, 2 -> 3 +// f(uint256[]): 32, 3, 100, 500, 300 -> 600 +// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55 diff --git a/examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars_standard_input.json b/examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars_standard_input.json new file mode 100644 index 00000000..85f0aa1f --- /dev/null +++ b/examples/test/semanticTests/functionCall_array_multiple_local_vars/array_multiple_local_vars_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy.sol b/examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy.sol new file mode 100644 index 00000000..17b6f74c --- /dev/null +++ b/examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy.sol @@ -0,0 +1,8 @@ +contract C { + function f() public returns (bool) { + (bool success, ) = address(1).call(""); + return success; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy_standard_input.json b/examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy_standard_input.json new file mode 100644 index 00000000..abbb9f86 --- /dev/null +++ b/examples/test/semanticTests/functionCall_bare_call_no_returndatacopy/bare_call_no_returndatacopy_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function.sol b/examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function.sol new file mode 100644 index 00000000..023133a4 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function.sol @@ -0,0 +1,13 @@ +library L { + function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); } +} +contract C { + using L for *; + function f() public returns (uint) { + return t.g(); + } + function t() public pure returns (uint) { return 7; } +} +// ---- +// library: L +// f() -> 7 diff --git a/examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function_standard_input.json b/examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function_standard_input.json new file mode 100644 index 00000000..81f8d6c8 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_attached_library_function_on_function/call_attached_library_function_on_function_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable.sol b/examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable.sol new file mode 100644 index 00000000..5a599c8a --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable.sol @@ -0,0 +1,13 @@ +library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 6; + return (x.mul)({x: a}); + } +} +// ---- +// library: D +// f(uint256): 7 -> 0x2a +// x() -> 0x2a diff --git a/examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable_standard_input.json b/examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable_standard_input.json new file mode 100644 index 00000000..6c51846f --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_attached_library_function_on_storage_variable/call_attached_library_function_on_storage_variable_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string.sol b/examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string.sol new file mode 100644 index 00000000..d2d23fb6 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string.sol @@ -0,0 +1,17 @@ +library D { function length(string memory self) public returns (uint) { return bytes(self).length; } } +contract C { + using D for string; + string x; + function f() public returns (uint) { + x = "abc"; + return x.length(); + } + function g() public returns (uint) { + string memory s = "abc"; + return s.length(); + } +} +// ---- +// library: D +// f() -> 3 +// g() -> 3 diff --git a/examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string_standard_input.json b/examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string_standard_input.json new file mode 100644 index 00000000..fe9430b7 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_attached_library_function_on_string/call_attached_library_function_on_string_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function.sol b/examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function.sol new file mode 100644 index 00000000..a00628ea --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function.sol @@ -0,0 +1,25 @@ +contract test { + function f0() public returns (uint) { + return 2; + } + + function f1() internal returns (function() internal returns (uint)) { + return f0; + } + + function f2() internal returns (function() internal returns (function () internal returns (uint))) { + return f1; + } + + function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) { + return f2; + } + + function f() public returns (uint) { + function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x; + x = f3; + return x()()()(); + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function_standard_input.json b/examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function_standard_input.json new file mode 100644 index 00000000..b343293e --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_function_returning_function/call_function_returning_function_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer.sol b/examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer.sol new file mode 100644 index 00000000..b43c453d --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer.sol @@ -0,0 +1,16 @@ +contract test { + bool public flag = false; + + function f0() public { + flag = true; + } + + function f() public returns (bool) { + function() internal x = f0; + x(); + return flag; + } +} +// ---- +// f() -> true +// flag() -> true diff --git a/examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer_standard_input.json b/examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer_standard_input.json new file mode 100644 index 00000000..adc1f569 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_function_returning_nothing_via_pointer/call_function_returning_nothing_via_pointer_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression.sol b/examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression.sol new file mode 100644 index 00000000..0b880bfd --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression.sol @@ -0,0 +1,22 @@ +contract C { + function foo() internal returns (uint) { + return 42; + } + + function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) { + return ptr; + } + + function associated() public returns (uint) { + // This expression directly references function definition + return (foo)(); + } + + function unassociated() public returns (uint) { + // This expression is not associated with a specific function definition + return (get_ptr(foo))(); + } +} +// ---- +// associated() -> 42 +// unassociated() -> 42 diff --git a/examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression_standard_input.json b/examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression_standard_input.json new file mode 100644 index 00000000..f8818841 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_internal_function_via_expression/call_internal_function_via_expression_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + }, + "call_internal_function_via_expression.sol": { + "content": "contract C {\n function foo() internal returns (uint) {\n return 42;\n }\n\n function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n return ptr;\n }\n\n function associated() public returns (uint) {\n // This expression directly references function definition\n return (foo)();\n }\n\n function unassociated() public returns (uint) {\n // This expression is not associated with a specific function definition\n return (get_ptr(foo))();\n }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer.sol b/examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer.sol new file mode 100644 index 00000000..a93adf24 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer.sol @@ -0,0 +1,29 @@ +contract C { + function m( + function() external returns (uint) a, + function() external returns (uint) b + ) internal returns (function() external returns (uint)) { + return a; + } + + function s(uint a, uint b) internal returns (uint) { + return a + b; + } + + function foo() external returns (uint) { + return 6; + } + + function test() public returns (uint) { + function(uint, uint) internal returns (uint) single_slot_function = s; + + function( + function() external returns (uint), + function() external returns (uint) + ) internal returns (function() external returns (uint)) multi_slot_function = m; + + return multi_slot_function(this.foo, this.foo)() + single_slot_function(5, 1); + } +} +// ---- +// test() -> 12 diff --git a/examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer_standard_input.json b/examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer_standard_input.json new file mode 100644 index 00000000..b4459d46 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_internal_function_with_multislot_arguments_via_pointer/call_internal_function_with_multislot_arguments_via_pointer_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + }, + "call_internal_function_via_expression.sol": { + "content": "contract C {\n function foo() internal returns (uint) {\n return 42;\n }\n\n function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n return ptr;\n }\n\n function associated() public returns (uint) {\n // This expression directly references function definition\n return (foo)();\n }\n\n function unassociated() public returns (uint) {\n // This expression is not associated with a specific function definition\n return (get_ptr(foo))();\n }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n" + }, + "external_call_value.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external payable returns (uint, uint) {\n return (msg.value * 1000, n);\n }\n\n function f(uint n) public payable returns (uint, uint) {\n return this.g{value: 10}(n);\n }\n}\n// ----\n// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4\n// f(uint256), 11 ether: 2 -> 10000, 2\n" + }, + "call_internal_function_with_multislot_arguments_via_pointer.sol": { + "content": "contract C {\n function m(\n function() external returns (uint) a,\n function() external returns (uint) b\n ) internal returns (function() external returns (uint)) {\n return a;\n }\n\n function s(uint a, uint b) internal returns (uint) {\n return a + b;\n }\n\n function foo() external returns (uint) {\n return 6;\n }\n\n function test() public returns (uint) {\n function(uint, uint) internal returns (uint) single_slot_function = s;\n\n function(\n function() external returns (uint),\n function() external returns (uint)\n ) internal returns (function() external returns (uint)) multi_slot_function = m;\n\n return multi_slot_function(this.foo, this.foo)() + single_slot_function(5, 1);\n }\n}\n// ----\n// test() -> 12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_call_options_overload/call_options_overload.sol b/examples/test/semanticTests/functionCall_call_options_overload/call_options_overload.sol new file mode 100644 index 00000000..b9eb6ca4 --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_options_overload/call_options_overload.sol @@ -0,0 +1,16 @@ +contract C { + function f(uint x) external payable returns (uint) { return 1; } + function f(uint x, uint y) external payable returns (uint) { return 2; } + function call() public payable returns (uint v, uint x, uint y, uint z) { + v = this.f{value: 10}(2); + x = this.f{gas: 10000}(2, 3); + y = this.f{gas: 10000, value: 10}(2, 3); + z = this.f{value: 10, gas: 10000}(2, 3); + } + function bal() external returns (uint) { return address(this).balance; } + receive() external payable {} +} +// ---- +// (), 1 ether +// call() -> 1, 2, 2, 2 +// bal() -> 1000000000000000000 diff --git a/examples/test/semanticTests/functionCall_call_options_overload/call_options_overload_standard_input.json b/examples/test/semanticTests/functionCall_call_options_overload/call_options_overload_standard_input.json new file mode 100644 index 00000000..183ca41e --- /dev/null +++ b/examples/test/semanticTests/functionCall_call_options_overload/call_options_overload_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws.sol b/examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws.sol new file mode 100644 index 00000000..22961838 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws.sol @@ -0,0 +1,27 @@ +abstract contract D { + function g() public virtual; +} + + +contract C { + D d = D(address(0x1212)); + + function f() public returns (uint256) { + d.g(); + return 7; + } + + function g() public returns (uint256) { + d.g{gas: 200}(); + return 7; + } + + function h() public returns (uint256) { + address(d).call(""); // this does not throw (low-level) + return 7; + } +} +// ---- +// f() -> FAILURE +// g() -> FAILURE +// h() -> 7 diff --git a/examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws_standard_input.json b/examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws_standard_input.json new file mode 100644 index 00000000..4e413012 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_nonexisting_contract_throws/calling_nonexisting_contract_throws_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions.sol b/examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions.sol new file mode 100644 index 00000000..9b008f12 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions.sol @@ -0,0 +1,20 @@ +contract collatz { + function run(uint x) public returns(uint y) { + while ((y = x) > 1) { + if (x % 2 == 0) x = evenStep(x); + else x = oddStep(x); + } + } + function evenStep(uint x) public returns(uint y) { + return x / 2; + } + function oddStep(uint x) public returns(uint y) { + return 3 * x + 1; + } +} +// ---- +// run(uint256): 0 -> 0 +// run(uint256): 1 -> 1 +// run(uint256): 2 -> 1 +// run(uint256): 8 -> 1 +// run(uint256): 127 -> 1 diff --git a/examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions_standard_input.json b/examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions_standard_input.json new file mode 100644 index 00000000..7340af87 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_other_functions/calling_other_functions_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + }, + "call_internal_function_via_expression.sol": { + "content": "contract C {\n function foo() internal returns (uint) {\n return 42;\n }\n\n function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n return ptr;\n }\n\n function associated() public returns (uint) {\n // This expression directly references function definition\n return (foo)();\n }\n\n function unassociated() public returns (uint) {\n // This expression is not associated with a specific function definition\n return (get_ptr(foo))();\n }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n" + }, + "external_call_value.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external payable returns (uint, uint) {\n return (msg.value * 1000, n);\n }\n\n function f(uint n) public payable returns (uint, uint) {\n return this.g{value: 10}(n);\n }\n}\n// ----\n// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4\n// f(uint256), 11 ether: 2 -> 10000, 2\n" + }, + "call_internal_function_with_multislot_arguments_via_pointer.sol": { + "content": "contract C {\n function m(\n function() external returns (uint) a,\n function() external returns (uint) b\n ) internal returns (function() external returns (uint)) {\n return a;\n }\n\n function s(uint a, uint b) internal returns (uint) {\n return a + b;\n }\n\n function foo() external returns (uint) {\n return 6;\n }\n\n function test() public returns (uint) {\n function(uint, uint) internal returns (uint) single_slot_function = s;\n\n function(\n function() external returns (uint),\n function() external returns (uint)\n ) internal returns (function() external returns (uint)) multi_slot_function = m;\n\n return multi_slot_function(this.foo, this.foo)() + single_slot_function(5, 1);\n }\n}\n// ----\n// test() -> 12\n" + }, + "gas_and_value_brace_syntax.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() payable public returns(uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns(bool fl) {\n return flag;\n }\n}\ncontract test {\n helper h;\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint amount) public payable returns(uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns(bool ret) {\n h.setFlag {\n gas: 2\n }(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns(bool flagAfter, uint myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "calling_uninitialized_function_through_array.sol": { + "content": "contract C {\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n function() internal returns (uint)[200] memory x;\n x[0]();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "calling_other_functions.sol": { + "content": "contract collatz {\n function run(uint x) public returns(uint y) {\n while ((y = x) > 1) {\n if (x % 2 == 0) x = evenStep(x);\n else x = oddStep(x);\n }\n }\n function evenStep(uint x) public returns(uint y) {\n return x / 2;\n }\n function oddStep(uint x) public returns(uint y) {\n return 3 * x + 1;\n }\n}\n// ----\n// run(uint256): 0 -> 0\n// run(uint256): 1 -> 1\n// run(uint256): 2 -> 1\n// run(uint256): 8 -> 1\n// run(uint256): 127 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function.sol b/examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function.sol new file mode 100644 index 00000000..701b1f51 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function.sol @@ -0,0 +1,16 @@ +contract C { + function intern() public returns (uint256) { + function (uint) internal returns (uint) x; + x(2); + return 7; + } + + function extern() public returns (uint256) { + function (uint) external returns (uint) x; + x(2); + return 7; + } +} +// ---- +// intern() -> FAILURE, hex"4e487b71", 0x51 # This should throw exceptions # +// extern() -> FAILURE diff --git a/examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function_standard_input.json b/examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function_standard_input.json new file mode 100644 index 00000000..afe7798d --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_uninitialized_function/calling_uninitialized_function_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail.sol b/examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail.sol new file mode 100644 index 00000000..aa455afc --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail.sol @@ -0,0 +1,19 @@ +contract C { + function() returns (uint256) internal x; + int256 mutex; + + function t() public returns (uint256) { + if (mutex > 0) { + assembly { + mstore(0, 7) + return(0, 0x20) + } + } + mutex = 1; + // Avoid re-executing this function if we jump somewhere. + x(); + return 2; + } +} +// ---- +// t() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail_standard_input.json b/examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail_standard_input.json new file mode 100644 index 00000000..4f90f658 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_uninitialized_function_in_detail/calling_uninitialized_function_in_detail_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array.sol b/examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array.sol new file mode 100644 index 00000000..d83fab85 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array.sol @@ -0,0 +1,19 @@ +contract C { + int256 mutex; + + function t() public returns (uint256) { + if (mutex > 0) { + assembly { + mstore(0, 7) + return(0, 0x20) + } + } + mutex = 1; + // Avoid re-executing this function if we jump somewhere. + function() internal returns (uint)[200] memory x; + x[0](); + return 2; + } +} +// ---- +// t() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array_standard_input.json b/examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array_standard_input.json new file mode 100644 index 00000000..2a9bf463 --- /dev/null +++ b/examples/test/semanticTests/functionCall_calling_uninitialized_function_through_array/calling_uninitialized_function_through_array_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + }, + "call_internal_function_via_expression.sol": { + "content": "contract C {\n function foo() internal returns (uint) {\n return 42;\n }\n\n function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n return ptr;\n }\n\n function associated() public returns (uint) {\n // This expression directly references function definition\n return (foo)();\n }\n\n function unassociated() public returns (uint) {\n // This expression is not associated with a specific function definition\n return (get_ptr(foo))();\n }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n" + }, + "external_call_value.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external payable returns (uint, uint) {\n return (msg.value * 1000, n);\n }\n\n function f(uint n) public payable returns (uint, uint) {\n return this.g{value: 10}(n);\n }\n}\n// ----\n// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4\n// f(uint256), 11 ether: 2 -> 10000, 2\n" + }, + "call_internal_function_with_multislot_arguments_via_pointer.sol": { + "content": "contract C {\n function m(\n function() external returns (uint) a,\n function() external returns (uint) b\n ) internal returns (function() external returns (uint)) {\n return a;\n }\n\n function s(uint a, uint b) internal returns (uint) {\n return a + b;\n }\n\n function foo() external returns (uint) {\n return 6;\n }\n\n function test() public returns (uint) {\n function(uint, uint) internal returns (uint) single_slot_function = s;\n\n function(\n function() external returns (uint),\n function() external returns (uint)\n ) internal returns (function() external returns (uint)) multi_slot_function = m;\n\n return multi_slot_function(this.foo, this.foo)() + single_slot_function(5, 1);\n }\n}\n// ----\n// test() -> 12\n" + }, + "gas_and_value_brace_syntax.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() payable public returns(uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns(bool fl) {\n return flag;\n }\n}\ncontract test {\n helper h;\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint amount) public payable returns(uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns(bool ret) {\n h.setFlag {\n gas: 2\n }(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns(bool flagAfter, uint myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "calling_uninitialized_function_through_array.sol": { + "content": "contract C {\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n function() internal returns (uint)[200] memory x;\n x[0]();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments.sol b/examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments.sol new file mode 100644 index 00000000..f5996d32 --- /dev/null +++ b/examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments.sol @@ -0,0 +1,10 @@ +contract C { + function g(int x, int y) public pure returns (int) { return x - y; } + function h(int y, int x) public pure returns (int) { return y - x; } + + function f() public pure returns (int) { + return (false ? g : h)(2, 1); + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments_standard_input.json b/examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments_standard_input.json new file mode 100644 index 00000000..abff1e91 --- /dev/null +++ b/examples/test/semanticTests/functionCall_conditional_with_arguments/conditional_with_arguments_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args.sol b/examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args.sol new file mode 100644 index 00000000..60440659 --- /dev/null +++ b/examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args.sol @@ -0,0 +1,15 @@ +contract C { + uint public i; + constructor() { + i = 2; + } +} +contract D { + function f() public returns (uint r) { + return new C().i(); + } +} +// ---- +// f() -> 2 +// gas legacy: 76585 +// gas legacy code: 23600 diff --git a/examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args_standard_input.json b/examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args_standard_input.json new file mode 100644 index 00000000..57052a8d --- /dev/null +++ b/examples/test/semanticTests/functionCall_creation_function_call_no_args/creation_function_call_no_args_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args.sol b/examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args.sol new file mode 100644 index 00000000..08e9f36f --- /dev/null +++ b/examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args.sol @@ -0,0 +1,24 @@ +contract C { + uint public i; + constructor(uint newI) { + i = newI; + } +} +contract D { + C c; + constructor(uint v) { + c = new C(v); + } + function f() public returns (uint r) { + return c.i(); + } +} +// ---- +// constructor(): 2 -> +// gas irOptimized: 138930 +// gas irOptimized code: 53800 +// gas legacy: 145569 +// gas legacy code: 95600 +// gas legacyOptimized: 138297 +// gas legacyOptimized code: 54600 +// f() -> 2 diff --git a/examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args_standard_input.json b/examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args_standard_input.json new file mode 100644 index 00000000..1c5d5216 --- /dev/null +++ b/examples/test/semanticTests/functionCall_creation_function_call_with_args/creation_function_call_with_args_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt.sol b/examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt.sol new file mode 100644 index 00000000..320b1056 --- /dev/null +++ b/examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt.sol @@ -0,0 +1,26 @@ +contract C { + uint public i; + constructor(uint newI) { + i = newI; + } +} +contract D { + C c; + constructor(uint v) { + c = new C{salt: "abc"}(v); + } + function f() public returns (uint r) { + return c.i(); + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// constructor(): 2 -> +// gas irOptimized: 139112 +// gas irOptimized code: 53800 +// gas legacy: 145935 +// gas legacy code: 95600 +// gas legacyOptimized: 138529 +// gas legacyOptimized code: 54600 +// f() -> 2 diff --git a/examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt_standard_input.json b/examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt_standard_input.json new file mode 100644 index 00000000..dc8ded66 --- /dev/null +++ b/examples/test/semanticTests/functionCall_creation_function_call_with_salt/creation_function_call_with_salt_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value.sol b/examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value.sol new file mode 100644 index 00000000..1e6d542c --- /dev/null +++ b/examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value.sol @@ -0,0 +1,37 @@ +contract C { + uint256 value; + + function set(uint256 _value) external { + value = _value; + } + + function get() external view returns (uint256) { + return value; + } + + function get_delegated() external returns (bool, bytes memory) { + return address(this).delegatecall(abi.encodeWithSignature("get()")); + } + + function assert0() external view { + assert(value == 0); + } + + function assert0_delegated() external returns (bool, bytes memory) { + return address(this).delegatecall(abi.encodeWithSignature("assert0()")); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// get() -> 0x00 +// assert0_delegated() -> 0x01, 0x40, 0x0 +// get_delegated() -> 0x01, 0x40, 0x20, 0x0 +// set(uint256): 0x01 -> +// get() -> 0x01 +// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000 +// get_delegated() -> 0x01, 0x40, 0x20, 0x1 +// set(uint256): 0x2a -> +// get() -> 0x2a +// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000 +// get_delegated() -> 0x01, 0x40, 0x20, 0x2a diff --git a/examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value_standard_input.json b/examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value_standard_input.json new file mode 100644 index 00000000..967b53c0 --- /dev/null +++ b/examples/test/semanticTests/functionCall_delegatecall_return_value/delegatecall_return_value_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium.sol b/examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium.sol new file mode 100644 index 00000000..498449d1 --- /dev/null +++ b/examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium.sol @@ -0,0 +1,39 @@ +contract C { + uint256 value; + + function set(uint256 _value) external { + value = _value; + } + + function get() external view returns (uint256) { + return value; + } + + function get_delegated() external returns (bool) { + (bool success,) = address(this).delegatecall(abi.encodeWithSignature("get()")); + return success; + } + + function assert0() external view { + assert(value == 0); + } + + function assert0_delegated() external returns (bool) { + (bool success,) = address(this).delegatecall(abi.encodeWithSignature("assert0()")); + return success; + } +} +// ==== +// EVMVersion: 0x00 +// assert0_delegated() -> true +// get_delegated() -> true +// set(uint256): 0x01 -> +// get() -> 0x01 +// assert0_delegated() -> false +// get_delegated() -> true +// set(uint256): 0x2a -> +// get() -> 0x2a +// assert0_delegated() -> false +// get_delegated() -> true diff --git a/examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium_standard_input.json b/examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium_standard_input.json new file mode 100644 index 00000000..512a3d9b --- /dev/null +++ b/examples/test/semanticTests/functionCall_delegatecall_return_value_pre_byzantium/delegatecall_return_value_pre_byzantium_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args.sol b/examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args.sol new file mode 100644 index 00000000..f15d2201 --- /dev/null +++ b/examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args.sol @@ -0,0 +1,6 @@ +contract test { + function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); } +} +// ---- +// b() -> 123 diff --git a/examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args_standard_input.json b/examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args_standard_input.json new file mode 100644 index 00000000..bfc98b84 --- /dev/null +++ b/examples/test/semanticTests/functionCall_disordered_named_args/disordered_named_args_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_call/external_call.sol b/examples/test/semanticTests/functionCall_external_call/external_call.sol new file mode 100644 index 00000000..9189d5cc --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call/external_call.sol @@ -0,0 +1,14 @@ +pragma solidity >= 0.6.0; + +contract C { + function g(uint n) external pure returns (uint) { + return n + 1; + } + + function f(uint n) public view returns (uint) { + return this.g(2 * n); + } +} +// ---- +// g(uint256): 4 -> 5 +// f(uint256): 2 -> 5 diff --git a/examples/test/semanticTests/functionCall_external_call/external_call_standard_input.json b/examples/test/semanticTests/functionCall_external_call/external_call_standard_input.json new file mode 100644 index 00000000..094247d3 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call/external_call_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time.sol b/examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time.sol new file mode 100644 index 00000000..6f7f020f --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time.sol @@ -0,0 +1,24 @@ +// This tests skipping the extcodesize check. + +contract T { + constructor() { this.f(); } + function f() external {} +} +contract U { + constructor() { this.f(); } + function f() external returns (uint) {} +} + +contract C { + function f(uint c) external returns (uint) { + if (c == 0) new T(); + else if (c == 1) new U(); + return 1 + c; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> 3 diff --git a/examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time_standard_input.json b/examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time_standard_input.json new file mode 100644 index 00000000..2836ee01 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_at_construction_time/external_call_at_construction_time_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata.sol b/examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata.sol new file mode 100644 index 00000000..80ca6cc4 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata.sol @@ -0,0 +1,22 @@ +pragma solidity >= 0.6.0; + +contract C { + function d(uint n) external pure returns (uint[] memory) { + uint[] memory data = new uint[](n); + for (uint i = 0; i < data.length; ++i) + data[i] = i; + return data; + } + + function dt(uint n) public view returns (uint) { + uint[] memory data = this.d(n); + uint sum = 0; + for (uint i = 0; i < data.length; ++i) + sum += data[i]; + return sum; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// dt(uint256): 4 -> 6 diff --git a/examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata_standard_input.json b/examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata_standard_input.json new file mode 100644 index 00000000..ec4627fd --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_dynamic_returndata/external_call_dynamic_returndata_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting.sol b/examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting.sol new file mode 100644 index 00000000..472921c1 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting.sol @@ -0,0 +1,37 @@ +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 88853 +// gas irOptimized code: 164400 +// gas legacy: 102721 +// gas legacy code: 334400 +// gas legacyOptimized: 91499 +// gas legacyOptimized code: 196400 +// f(uint256): 0 -> FAILURE +// f(uint256): 1 -> FAILURE +// f(uint256): 2 -> FAILURE +// f(uint256): 3 -> FAILURE +// f(uint256): 4 -> FAILURE +// f(uint256): 5 -> FAILURE +// f(uint256): 6 -> 7 diff --git a/examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting_standard_input.json b/examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting_standard_input.json new file mode 100644 index 00000000..2e388af3 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_to_nonexisting/external_call_to_nonexisting_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings.sol b/examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings.sol new file mode 100644 index 00000000..d1b6e8e8 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings.sol @@ -0,0 +1,40 @@ +// This tests skipping the extcodesize check. + +interface I { + function a() external pure; + function b() external; + function c() external payable; + function x() external returns (uint); + function y() external returns (string memory); +} +contract C { + I i = I(address(0xcafecafe)); + constructor() payable {} + function f(uint c) external returns (uint) { + if (c == 0) i.a(); + else if (c == 1) i.b(); + else if (c == 2) i.c(); + else if (c == 3) i.c{value: 1}(); + else if (c == 4) i.x(); + else if (c == 5) i.y(); + return 1 + c; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 98698 +// gas irOptimized code: 284200 +// gas legacy: 123258 +// gas legacy code: 682400 +// gas legacyOptimized: 106969 +// gas legacyOptimized code: 386400 +// f(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 1 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 2 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 3 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 4 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 5 -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" +// f(uint256): 6 -> 7 diff --git a/examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings_standard_input.json b/examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings_standard_input.json new file mode 100644 index 00000000..d0919780 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_to_nonexisting_debugstrings/external_call_to_nonexisting_debugstrings_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_call_value/external_call_value.sol b/examples/test/semanticTests/functionCall_external_call_value/external_call_value.sol new file mode 100644 index 00000000..9639c111 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_value/external_call_value.sol @@ -0,0 +1,14 @@ +pragma solidity >= 0.6.0; + +contract C { + function g(uint n) external payable returns (uint, uint) { + return (msg.value * 1000, n); + } + + function f(uint n) public payable returns (uint, uint) { + return this.g{value: 10}(n); + } +} +// ---- +// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4 +// f(uint256), 11 ether: 2 -> 10000, 2 diff --git a/examples/test/semanticTests/functionCall_external_call_value/external_call_value_standard_input.json b/examples/test/semanticTests/functionCall_external_call_value/external_call_value_standard_input.json new file mode 100644 index 00000000..c5ef0e75 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_call_value/external_call_value_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + }, + "call_internal_function_via_expression.sol": { + "content": "contract C {\n function foo() internal returns (uint) {\n return 42;\n }\n\n function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n return ptr;\n }\n\n function associated() public returns (uint) {\n // This expression directly references function definition\n return (foo)();\n }\n\n function unassociated() public returns (uint) {\n // This expression is not associated with a specific function definition\n return (get_ptr(foo))();\n }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n" + }, + "external_call_value.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external payable returns (uint, uint) {\n return (msg.value * 1000, n);\n }\n\n function f(uint n) public payable returns (uint, uint) {\n return this.g{value: 10}(n);\n }\n}\n// ----\n// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4\n// f(uint256), 11 ether: 2 -> 10000, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_function/external_function.sol b/examples/test/semanticTests/functionCall_external_function/external_function.sol new file mode 100644 index 00000000..284bad09 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_function/external_function.sol @@ -0,0 +1,15 @@ +contract c { + function f(uint256 a) public returns (uint256) { + return a; + } + + function test(uint256 a, uint256 b) + external + returns (uint256 r_a, uint256 r_b) + { + r_a = f(a + 7); + r_b = b; + } +} +// ---- +// test(uint256,uint256): 2, 3 -> 9, 3 diff --git a/examples/test/semanticTests/functionCall_external_function/external_function_standard_input.json b/examples/test/semanticTests/functionCall_external_function/external_function_standard_input.json new file mode 100644 index 00000000..97b163fb --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_function/external_function_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_external_public_override/external_public_override.sol b/examples/test/semanticTests/functionCall_external_public_override/external_public_override.sol new file mode 100644 index 00000000..8e34a5b2 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_public_override/external_public_override.sol @@ -0,0 +1,19 @@ +contract A { + function f() external virtual returns (uint256) { + return 1; + } +} + + +contract B is A { + function f() public override returns (uint256) { + return 2; + } + + function g() public returns (uint256) { + return f(); + } +} +// ---- +// f() -> 2 +// g() -> 2 diff --git a/examples/test/semanticTests/functionCall_external_public_override/external_public_override_standard_input.json b/examples/test/semanticTests/functionCall_external_public_override/external_public_override_standard_input.json new file mode 100644 index 00000000..9f7495a6 --- /dev/null +++ b/examples/test/semanticTests/functionCall_external_public_override/external_public_override_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_failed_create/failed_create.sol b/examples/test/semanticTests/functionCall_failed_create/failed_create.sol new file mode 100644 index 00000000..657b4b5c --- /dev/null +++ b/examples/test/semanticTests/functionCall_failed_create/failed_create.sol @@ -0,0 +1,36 @@ +contract D { constructor() payable {} } +contract C { + uint public x; + constructor() payable {} + function f(uint amount) public returns (D) { + x++; + return (new D){value: amount}(); + } + function stack(uint depth) public payable returns (address) { + if (depth > 0) + return this.stack(depth - 1); + else + return address(f(0)); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// constructor(), 20 wei +// gas irOptimized: 61548 +// gas irOptimized code: 104600 +// gas legacy: 70147 +// gas legacy code: 215400 +// gas legacyOptimized: 61715 +// gas legacyOptimized code: 106800 +// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a +// x() -> 1 +// f(uint256): 20 -> FAILURE +// x() -> 1 +// stack(uint256): 1023 -> FAILURE +// gas irOptimized: 252410 +// gas legacy: 476845 +// gas legacyOptimized: 299061 +// x() -> 1 +// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908 +// x() -> 2 diff --git a/examples/test/semanticTests/functionCall_failed_create/failed_create_standard_input.json b/examples/test/semanticTests/functionCall_failed_create/failed_create_standard_input.json new file mode 100644 index 00000000..b2839460 --- /dev/null +++ b/examples/test/semanticTests/functionCall_failed_create/failed_create_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module.sol b/examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module.sol new file mode 100644 index 00000000..7013a635 --- /dev/null +++ b/examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module.sol @@ -0,0 +1,13 @@ +==== Source: a.sol ==== +function f(uint) pure returns (uint) { return 7; } +function f(bytes memory x) pure returns (uint) { return x.length; } +==== Source: b.sol ==== +import "a.sol" as M; +contract C { + function f() public pure returns (uint, uint) { + return (M.f(2), M.f("abc")); + + } +} +// ---- +// f() -> 7, 3 diff --git a/examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module_standard_input.json b/examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module_standard_input.json new file mode 100644 index 00000000..c82081c1 --- /dev/null +++ b/examples/test/semanticTests/functionCall_file_level_call_via_module/file_level_call_via_module_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic.sol b/examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic.sol new file mode 100644 index 00000000..e6187d06 --- /dev/null +++ b/examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic.sol @@ -0,0 +1,49 @@ +contract helper { + bool flag; + + function getBalance() public payable returns (uint256 myBalance) { + return address(this).balance; + } + + function setFlag() public { + flag = true; + } + + function getFlag() public returns (bool fl) { + return flag; + } +} + + +contract test { + helper h; + + constructor() payable { + h = new helper(); + } + + function sendAmount(uint256 amount) public payable returns (uint256 bal) { + return h.getBalance{value: amount}(); + } + + function outOfGas() public returns (bool ret) { + h.setFlag{gas: 2}(); // should fail due to OOG + return true; + } + + function checkState() public returns (bool flagAfter, uint256 myBal) { + flagAfter = h.getFlag(); + myBal = address(this).balance; + } +} +// ---- +// constructor(), 20 wei -> +// gas irOptimized: 120218 +// gas irOptimized code: 132000 +// gas legacy: 130583 +// gas legacy code: 261200 +// gas legacyOptimized: 121069 +// gas legacyOptimized code: 147000 +// sendAmount(uint256): 5 -> 5 +// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # +// checkState() -> false, 15 diff --git a/examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic_standard_input.json b/examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic_standard_input.json new file mode 100644 index 00000000..5b406ebc --- /dev/null +++ b/examples/test/semanticTests/functionCall_gas_and_value_basic/gas_and_value_basic_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax.sol b/examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax.sol new file mode 100644 index 00000000..41079af0 --- /dev/null +++ b/examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax.sol @@ -0,0 +1,48 @@ +contract helper { + bool flag; + + function getBalance() payable public returns(uint256 myBalance) { + return address(this).balance; + } + + function setFlag() public { + flag = true; + } + + function getFlag() public returns(bool fl) { + return flag; + } +} +contract test { + helper h; + constructor() payable { + h = new helper(); + } + + function sendAmount(uint amount) public payable returns(uint256 bal) { + return h.getBalance{value: amount}(); + } + + function outOfGas() public returns(bool ret) { + h.setFlag { + gas: 2 + }(); // should fail due to OOG + return true; + } + + function checkState() public returns(bool flagAfter, uint myBal) { + flagAfter = h.getFlag(); + myBal = address(this).balance; + } +} +// ---- +// constructor(), 20 wei -> +// gas irOptimized: 120218 +// gas irOptimized code: 132000 +// gas legacy: 130583 +// gas legacy code: 261200 +// gas legacyOptimized: 121069 +// gas legacyOptimized code: 147000 +// sendAmount(uint256): 5 -> 5 +// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway # +// checkState() -> false, 15 diff --git a/examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax_standard_input.json b/examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax_standard_input.json new file mode 100644 index 00000000..c9e7a969 --- /dev/null +++ b/examples/test/semanticTests/functionCall_gas_and_value_brace_syntax/gas_and_value_brace_syntax_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + }, + "gas_and_value_basic.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns (bool fl) {\n return flag;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns (bool ret) {\n h.setFlag{gas: 2}(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns (bool flagAfter, uint256 myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + }, + "bare_call_no_returndatacopy.sol": { + "content": "contract C {\n function f() public returns (bool) {\n (bool success, ) = address(1).call(\"\");\n return success;\n }\n}\n// ----\n// f() -> true\n" + }, + "call_internal_function_via_expression.sol": { + "content": "contract C {\n function foo() internal returns (uint) {\n return 42;\n }\n\n function get_ptr(function() internal returns (uint) ptr) internal returns(function() internal returns (uint)) {\n return ptr;\n }\n\n function associated() public returns (uint) {\n // This expression directly references function definition\n return (foo)();\n }\n\n function unassociated() public returns (uint) {\n // This expression is not associated with a specific function definition\n return (get_ptr(foo))();\n }\n}\n// ----\n// associated() -> 42\n// unassociated() -> 42\n" + }, + "external_call_value.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external payable returns (uint, uint) {\n return (msg.value * 1000, n);\n }\n\n function f(uint n) public payable returns (uint, uint) {\n return this.g{value: 10}(n);\n }\n}\n// ----\n// g(uint256), 1 ether: 4 -> 1000000000000000000000, 4\n// f(uint256), 11 ether: 2 -> 10000, 2\n" + }, + "call_internal_function_with_multislot_arguments_via_pointer.sol": { + "content": "contract C {\n function m(\n function() external returns (uint) a,\n function() external returns (uint) b\n ) internal returns (function() external returns (uint)) {\n return a;\n }\n\n function s(uint a, uint b) internal returns (uint) {\n return a + b;\n }\n\n function foo() external returns (uint) {\n return 6;\n }\n\n function test() public returns (uint) {\n function(uint, uint) internal returns (uint) single_slot_function = s;\n\n function(\n function() external returns (uint),\n function() external returns (uint)\n ) internal returns (function() external returns (uint)) multi_slot_function = m;\n\n return multi_slot_function(this.foo, this.foo)() + single_slot_function(5, 1);\n }\n}\n// ----\n// test() -> 12\n" + }, + "gas_and_value_brace_syntax.sol": { + "content": "contract helper {\n bool flag;\n\n function getBalance() payable public returns(uint256 myBalance) {\n return address(this).balance;\n }\n\n function setFlag() public {\n flag = true;\n }\n\n function getFlag() public returns(bool fl) {\n return flag;\n }\n}\ncontract test {\n helper h;\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint amount) public payable returns(uint256 bal) {\n return h.getBalance{value: amount}();\n }\n\n function outOfGas() public returns(bool ret) {\n h.setFlag {\n gas: 2\n }(); // should fail due to OOG\n return true;\n }\n\n function checkState() public returns(bool flagAfter, uint myBal) {\n flagAfter = h.getFlag();\n myBal = address(this).balance;\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 120218\n// gas irOptimized code: 132000\n// gas legacy: 130583\n// gas legacy code: 261200\n// gas legacyOptimized: 121069\n// gas legacyOptimized code: 147000\n// sendAmount(uint256): 5 -> 5\n// outOfGas() -> FAILURE # call to helper should not succeed but amount should be transferred anyway #\n// checkState() -> false, 15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload.sol b/examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload.sol new file mode 100644 index 00000000..adf1200e --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload.sol @@ -0,0 +1,50 @@ +contract BaseBase { + uint public x; + uint public y; + function init(uint a, uint b) public virtual { + x = b; + y = a; + } + function init(uint a) public virtual { + x = a + 1; + } +} + +contract Base is BaseBase { + function init(uint a, uint b) public override { + x = a; + y = b; + } + function init(uint a) public override { + x = a; + } +} + +contract Child is Base { + function cInit(uint c) public { + Base.init(c); + } + function cInit(uint c, uint d) public { + Base.init(c, d); + } + function bInit(uint c) public { + BaseBase.init(c); + } + function bInit(uint c, uint d) public { + BaseBase.init(c, d); + } +} +// ---- +// x() -> 0 +// y() -> 0 +// cInit(uint256): 2 -> +// x() -> 2 +// y() -> 0 +// cInit(uint256,uint256): 3, 3 -> +// x() -> 3 +// y() -> 3 +// bInit(uint256): 4 -> +// x() -> 5 +// bInit(uint256,uint256): 9, 10 -> +// x() -> 10 +// y() -> 9 diff --git a/examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload_standard_input.json new file mode 100644 index 00000000..cfb50558 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_base_base_overload/base_base_overload_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "base_overload.sol": { + "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n" + }, + "super_skip_unimplemented_in_interface.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\ninterface I {\n function f() external returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base_base_explicit.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\t// calling base-bse function of a virtual overridden function.\n\t\treturn BaseBase.f(n);\n\t}\n\n\tfunction k(uint n) public returns (uint) {\n\t\t// Calling base-base function of a non-virtual function.\n\t\treturn BaseBase.s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n// k(uint256): 4 -> 16\n" + }, + "call_base_explicit.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn Base.f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "call_unimplemented_base.sol": { + "content": "abstract contract I\n{\n function a() internal view virtual returns(uint256);\n}\nabstract contract J is I\n{\n function a() internal view virtual override returns(uint256);\n}\nabstract contract V is J\n{\n function b() public view returns(uint256) { return a(); }\n}\ncontract C is V\n{\n function a() internal view override returns (uint256) { return 42; }\n}\n// ----\n// b() -> 42\n" + }, + "base_base_overload.sol": { + "content": "contract BaseBase {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public virtual {\n\t\tx = b;\n\t\ty = a;\n\t}\n\tfunction init(uint a) public virtual {\n\t\tx = a + 1;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction init(uint a, uint b) public override {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public override {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n\tfunction bInit(uint c) public {\n\t\tBaseBase.init(c);\n\t}\n\tfunction bInit(uint c, uint d) public {\n\t\tBaseBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n// bInit(uint256): 4 ->\n// x() -> 5\n// bInit(uint256,uint256): 9, 10 ->\n// x() -> 10\n// y() -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload.sol b/examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload.sol new file mode 100644 index 00000000..924431ec --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload.sol @@ -0,0 +1,29 @@ +contract Base { + uint public x; + uint public y; + function init(uint a, uint b) public { + x = a; + y = b; + } + function init(uint a) public { + x = a; + } +} + +contract Child is Base { + function cInit(uint c) public { + Base.init(c); + } + function cInit(uint c, uint d) public { + Base.init(c, d); + } +} +// ---- +// x() -> 0 +// y() -> 0 +// cInit(uint256): 2 -> +// x() -> 2 +// y() -> 0 +// cInit(uint256,uint256): 3, 3 -> +// x() -> 3 +// y() -> 3 diff --git a/examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload_standard_input.json new file mode 100644 index 00000000..c6c00d00 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_base_overload/base_overload_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "base_overload.sol": { + "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base/call_base.sol b/examples/test/semanticTests/functionCall_inheritance_call_base/call_base.sol new file mode 100644 index 00000000..8f0e93dd --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base/call_base.sol @@ -0,0 +1,13 @@ +contract Base { + function f(uint n) public returns (uint) { + return 2 * n; + } +} + +contract Child is Base { + function g(uint n) public returns (uint) { + return f(n); + } +} +// ---- +// g(uint256): 4 -> 8 diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base/call_base_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_call_base/call_base_standard_input.json new file mode 100644 index 00000000..b3acc6fc --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base/call_base_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base.sol b/examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base.sol new file mode 100644 index 00000000..8578a670 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base.sol @@ -0,0 +1,27 @@ +contract BaseBase { + function f(uint n) public virtual returns (uint) { + return 2 * n; + } + function s(uint n) public returns (uint) { + return 4 * n; + } +} + +contract Base is BaseBase { + function f(uint n) public virtual override returns (uint) { + return 3 * n; + } +} + +contract Child is Base { + function g(uint n) public returns (uint) { + return f(n); + } + + function h(uint n) public returns (uint) { + return s(n); + } +} +// ---- +// g(uint256): 4 -> 12 +// h(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base_standard_input.json new file mode 100644 index 00000000..08ec7688 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base_base/call_base_base_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit.sol b/examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit.sol new file mode 100644 index 00000000..f327b3f2 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit.sol @@ -0,0 +1,30 @@ +contract BaseBase { + function f(uint n) public virtual returns (uint) { + return 2 * n; + } + + function s(uint n) public returns (uint) { + return 4 * n; + } +} + +contract Base is BaseBase { + function f(uint n) public virtual override returns (uint) { + return 3 * n; + } +} + +contract Child is Base { + function g(uint n) public returns (uint) { + // calling base-bse function of a virtual overridden function. + return BaseBase.f(n); + } + + function k(uint n) public returns (uint) { + // Calling base-base function of a non-virtual function. + return BaseBase.s(n); + } +} +// ---- +// g(uint256): 4 -> 8 +// k(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit_standard_input.json new file mode 100644 index 00000000..c9890c57 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base_base_explicit/call_base_base_explicit_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "base_overload.sol": { + "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n" + }, + "super_skip_unimplemented_in_interface.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\ninterface I {\n function f() external returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base_base_explicit.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\t// calling base-bse function of a virtual overridden function.\n\t\treturn BaseBase.f(n);\n\t}\n\n\tfunction k(uint n) public returns (uint) {\n\t\t// Calling base-base function of a non-virtual function.\n\t\treturn BaseBase.s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n// k(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit.sol b/examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit.sol new file mode 100644 index 00000000..0a0cf465 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit.sol @@ -0,0 +1,13 @@ +contract Base { + function f(uint n) public returns (uint) { + return 2 * n; + } +} + +contract Child is Base { + function g(uint n) public returns (uint) { + return Base.f(n); + } +} +// ---- +// g(uint256): 4 -> 8 diff --git a/examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit_standard_input.json new file mode 100644 index 00000000..3fa66cc8 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_base_explicit/call_base_explicit_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "base_overload.sol": { + "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n" + }, + "super_skip_unimplemented_in_interface.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\ninterface I {\n function f() external returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base_base_explicit.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\t// calling base-bse function of a virtual overridden function.\n\t\treturn BaseBase.f(n);\n\t}\n\n\tfunction k(uint n) public returns (uint) {\n\t\t// Calling base-base function of a non-virtual function.\n\t\treturn BaseBase.s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n// k(uint256): 4 -> 16\n" + }, + "call_base_explicit.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn Base.f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base.sol b/examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base.sol new file mode 100644 index 00000000..21ab22e0 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base.sol @@ -0,0 +1,18 @@ +abstract contract I +{ + function a() internal view virtual returns(uint256); +} +abstract contract J is I +{ + function a() internal view virtual override returns(uint256); +} +abstract contract V is J +{ + function b() public view returns(uint256) { return a(); } +} +contract C is V +{ + function a() internal view override returns (uint256) { return 42; } +} +// ---- +// b() -> 42 diff --git a/examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base_standard_input.json new file mode 100644 index 00000000..30e633e9 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_call_unimplemented_base/call_unimplemented_base_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "base_overload.sol": { + "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n" + }, + "super_skip_unimplemented_in_interface.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\ninterface I {\n function f() external returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base_base_explicit.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\t// calling base-bse function of a virtual overridden function.\n\t\treturn BaseBase.f(n);\n\t}\n\n\tfunction k(uint n) public returns (uint) {\n\t\t// Calling base-base function of a non-virtual function.\n\t\treturn BaseBase.s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n// k(uint256): 4 -> 16\n" + }, + "call_base_explicit.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn Base.f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "call_unimplemented_base.sol": { + "content": "abstract contract I\n{\n function a() internal view virtual returns(uint256);\n}\nabstract contract J is I\n{\n function a() internal view virtual override returns(uint256);\n}\nabstract contract V is J\n{\n function b() public view returns(uint256) { return a(); }\n}\ncontract C is V\n{\n function a() internal view override returns (uint256) { return 42; }\n}\n// ----\n// b() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract.sol b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract.sol new file mode 100644 index 00000000..20774d69 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract.sol @@ -0,0 +1,19 @@ +contract A { + function f() public virtual returns (uint) { + return 42; + } +} + +abstract contract I { + function f() external virtual returns (uint); +} + +contract B is A, I { + function f() override(A, I) public returns (uint) { + // I.f() is before A.f() in the C3 linearized order + // but it has no implementation. + return super.f(); + } +} +// ---- +// f() -> 42 diff --git a/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract_standard_input.json new file mode 100644 index 00000000..e22c7f65 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_abstract_contract/super_skip_unimplemented_in_abstract_contract_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface.sol b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface.sol new file mode 100644 index 00000000..f5f05613 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface.sol @@ -0,0 +1,19 @@ +contract A { + function f() public virtual returns (uint) { + return 42; + } +} + +interface I { + function f() external returns (uint); +} + +contract B is A, I { + function f() override(A, I) public returns (uint) { + // I.f() is before A.f() in the C3 linearized order + // but it has no implementation. + return super.f(); + } +} +// ---- +// f() -> 42 diff --git a/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface_standard_input.json b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface_standard_input.json new file mode 100644 index 00000000..68d4c300 --- /dev/null +++ b/examples/test/semanticTests/functionCall_inheritance_super_skip_unimplemented_in_interface/super_skip_unimplemented_in_interface_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "call_base_base.sol": { + "content": "contract BaseBase {\n\tfunction f(uint n) public virtual returns (uint) {\n\t\treturn 2 * n;\n\t}\n\tfunction s(uint n) public returns (uint) {\n\t\treturn 4 * n;\n\t}\n}\n\ncontract Base is BaseBase {\n\tfunction f(uint n) public virtual override returns (uint) {\n\t\treturn 3 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n\n\tfunction h(uint n) public returns (uint) {\n\t\treturn s(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 12\n// h(uint256): 4 -> 16\n" + }, + "super_skip_unimplemented_in_abstract_contract.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\nabstract contract I {\n function f() external virtual returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + }, + "call_base.sol": { + "content": "contract Base {\n\tfunction f(uint n) public returns (uint) {\n\t\treturn 2 * n;\n\t}\n}\n\ncontract Child is Base {\n\tfunction g(uint n) public returns (uint) {\n\t\treturn f(n);\n\t}\n}\n// ----\n// g(uint256): 4 -> 8\n" + }, + "base_overload.sol": { + "content": "contract Base {\n\tuint public x;\n\tuint public y;\n\tfunction init(uint a, uint b) public {\n\t\tx = a;\n\t\ty = b;\n\t}\n\tfunction init(uint a) public {\n\t\tx = a;\n\t}\n}\n\ncontract Child is Base {\n\tfunction cInit(uint c) public {\n\t\tBase.init(c);\n\t}\n\tfunction cInit(uint c, uint d) public {\n\t\tBase.init(c, d);\n\t}\n}\n// ----\n// x() -> 0\n// y() -> 0\n// cInit(uint256): 2 ->\n// x() -> 2\n// y() -> 0\n// cInit(uint256,uint256): 3, 3 ->\n// x() -> 3\n// y() -> 3\n" + }, + "super_skip_unimplemented_in_interface.sol": { + "content": "contract A {\n function f() public virtual returns (uint) {\n return 42;\n }\n}\n\ninterface I {\n function f() external returns (uint);\n}\n\ncontract B is A, I {\n function f() override(A, I) public returns (uint) {\n // I.f() is before A.f() in the C3 linearized order\n // but it has no implementation.\n return super.f();\n }\n}\n// ----\n// f() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument.sol b/examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument.sol new file mode 100644 index 00000000..7505e20c --- /dev/null +++ b/examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument.sol @@ -0,0 +1,26 @@ +contract test { + mapping(uint8 => uint8)[2] a; + mapping(uint8 => uint8)[2] b; + function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) { + uint8 oldValue1 = m[0][key]; + uint8 oldValue2 = m[1][key]; + m[0][key] = value1; + m[1][key] = value2; + return (oldValue1, oldValue2); + } + function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) { + (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2); + (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2); + } + function get(uint8 key) public returns (uint8, uint8, uint8, uint8) { + return (a[0][key], a[1][key], b[0][key], b[1][key]); + } +} +// ---- +// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0 +// gas irOptimized: 111237 +// gas legacy: 113742 +// gas legacyOptimized: 111768 +// get(uint8): 1 -> 21, 22, 42, 43 +// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43 +// get(uint8): 1 -> 10, 30, 11, 31 diff --git a/examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument_standard_input.json b/examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument_standard_input.json new file mode 100644 index 00000000..e76ed79f --- /dev/null +++ b/examples/test/semanticTests/functionCall_mapping_array_internal_argument/mapping_array_internal_argument_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument.sol b/examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument.sol new file mode 100644 index 00000000..728be2c0 --- /dev/null +++ b/examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument.sol @@ -0,0 +1,21 @@ +contract test { + mapping(uint8 => uint8) a; + mapping(uint8 => uint8) b; + function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) { + uint8 oldValue = m[key]; + m[key] = value; + return oldValue; + } + function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) { + old_a = set_internal(a, key, value_a); + old_b = set_internal(b, key, value_b); + } + function get(uint8 key) public returns (uint8, uint8) { + return (a[key], b[key]); + } +} +// ---- +// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0 +// get(uint8): 1 -> 21, 42 +// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42 +// get(uint8): 1 -> 10, 11 diff --git a/examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument_standard_input.json b/examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument_standard_input.json new file mode 100644 index 00000000..fad95cdb --- /dev/null +++ b/examples/test/semanticTests/functionCall_mapping_internal_argument/mapping_internal_argument_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return.sol b/examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return.sol new file mode 100644 index 00000000..7756a92b --- /dev/null +++ b/examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return.sol @@ -0,0 +1,22 @@ +contract test { + mapping(uint8 => uint8) a; + mapping(uint8 => uint8) b; + function f() internal returns (mapping(uint8 => uint8) storage r) { + r = a; + r[1] = 42; + r = b; + r[1] = 84; + } + function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) { + f()[2] = 21; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) { + mapping(uint8 => uint8) storage m = f(); + m[2] = 17; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } +} +// ---- +// g() -> 0, 42, 0, 0, 84, 21 +// h() -> 0, 42, 0, 0, 84, 17 diff --git a/examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return_standard_input.json b/examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return_standard_input.json new file mode 100644 index 00000000..e5958337 --- /dev/null +++ b/examples/test/semanticTests/functionCall_mapping_internal_return/mapping_internal_return_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_member_accessors/member_accessors.sol b/examples/test/semanticTests/functionCall_member_accessors/member_accessors.sol new file mode 100644 index 00000000..ae5eab6d --- /dev/null +++ b/examples/test/semanticTests/functionCall_member_accessors/member_accessors.sol @@ -0,0 +1,22 @@ +contract test { + uint256 public data; + bytes6 public name; + bytes32 public a_hash; + address public an_address; + constructor() { + data = 8; + name = "Celina"; + a_hash = keccak256("\x7b"); + an_address = address(0x1337); + super_secret_data = 42; + } + uint256 super_secret_data; +} +// ==== +// allowNonExistingFunctions: true +// ---- +// data() -> 8 +// name() -> "Celina" +// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52 +// an_address() -> 0x1337 +// super_secret_data() -> FAILURE diff --git a/examples/test/semanticTests/functionCall_member_accessors/member_accessors_standard_input.json b/examples/test/semanticTests/functionCall_member_accessors/member_accessors_standard_input.json new file mode 100644 index 00000000..142812c7 --- /dev/null +++ b/examples/test/semanticTests/functionCall_member_accessors/member_accessors_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_multiple_functions/multiple_functions.sol b/examples/test/semanticTests/functionCall_multiple_functions/multiple_functions.sol new file mode 100644 index 00000000..3c60a13f --- /dev/null +++ b/examples/test/semanticTests/functionCall_multiple_functions/multiple_functions.sol @@ -0,0 +1,14 @@ +contract test { + function a() public returns(uint n) { return 0; } + function b() public returns(uint n) { return 1; } + function c() public returns(uint n) { return 2; } + function f() public returns(uint n) { return 3; } +} +// ==== +// allowNonExistingFunctions: true +// ---- +// a() -> 0 +// b() -> 1 +// c() -> 2 +// f() -> 3 +// i_am_not_there() -> FAILURE diff --git a/examples/test/semanticTests/functionCall_multiple_functions/multiple_functions_standard_input.json b/examples/test/semanticTests/functionCall_multiple_functions/multiple_functions_standard_input.json new file mode 100644 index 00000000..97ba7ca8 --- /dev/null +++ b/examples/test/semanticTests/functionCall_multiple_functions/multiple_functions_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + }, + "delegatecall_return_value_pre_byzantium.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n return success;\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool) {\n (bool success,) = address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n return success;\n }\n}\n// ====\n// EVMVersion: 0x00\n// assert0_delegated() -> true\n// get_delegated() -> true\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> false\n// get_delegated() -> true\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> false\n// get_delegated() -> true\n" + }, + "mapping_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function set_internal(mapping(uint8 => uint8) storage m, uint8 key, uint8 value) internal returns (uint8) {\n uint8 oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function set(uint8 key, uint8 value_a, uint8 value_b) public returns (uint8 old_a, uint8 old_b) {\n old_a = set_internal(a, key, value_a);\n old_b = set_internal(b, key, value_b);\n }\n function get(uint8 key) public returns (uint8, uint8) {\n return (a[key], b[key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8): 1, 21, 42 -> 0, 0\n// get(uint8): 1 -> 21, 42\n// set(uint8,uint8,uint8): 1, 10, 11 -> 21, 42\n// get(uint8): 1 -> 10, 11\n" + }, + "external_call_at_construction_time.sol": { + "content": "// This tests skipping the extcodesize check.\n\ncontract T {\n constructor() { this.f(); }\n function f() external {}\n}\ncontract U {\n constructor() { this.f(); }\n function f() external returns (uint) {}\n}\n\ncontract C {\n function f(uint c) external returns (uint) {\n if (c == 0) new T();\n else if (c == 1) new U();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> 3\n" + }, + "disordered_named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n}\n// ----\n// b() -> 123\n" + }, + "calling_uninitialized_function_in_detail.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n int256 mutex;\n\n function t() public returns (uint256) {\n if (mutex > 0) {\n assembly {\n mstore(0, 7)\n return(0, 0x20)\n }\n }\n mutex = 1;\n // Avoid re-executing this function if we jump somewhere.\n x();\n return 2;\n }\n}\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "failed_create.sol": { + "content": "contract D { constructor() payable {} }\ncontract C {\n\tuint public x;\n\tconstructor() payable {}\n\tfunction f(uint amount) public returns (D) {\n\t\tx++;\n\t\treturn (new D){value: amount}();\n\t}\n\tfunction stack(uint depth) public payable returns (address) {\n\t\tif (depth > 0)\n\t\t\treturn this.stack(depth - 1);\n\t\telse\n\t\t\treturn address(f(0));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// constructor(), 20 wei\n// gas irOptimized: 61548\n// gas irOptimized code: 104600\n// gas legacy: 70147\n// gas legacy code: 215400\n// gas legacyOptimized: 61715\n// gas legacyOptimized code: 106800\n// f(uint256): 20 -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// x() -> 1\n// f(uint256): 20 -> FAILURE\n// x() -> 1\n// stack(uint256): 1023 -> FAILURE\n// gas irOptimized: 252410\n// gas legacy: 476845\n// gas legacyOptimized: 299061\n// x() -> 1\n// stack(uint256): 10 -> 0x87948bd7ebbe13a00bfd930c93e4828ab18e3908\n// x() -> 2\n" + }, + "array_multiple_local_vars.sol": { + "content": "contract test {\n function f(uint256[] calldata seq) external pure returns (uint256) {\n uint i = 0;\n uint sum = 0;\n while (i < seq.length)\n {\n uint idx = i;\n if (idx >= 10) break;\n uint x = seq[idx];\n if (x >= 1000) {\n uint n = i + 1;\n i = n;\n continue;\n }\n else {\n uint y = sum + x;\n sum = y;\n }\n if (sum >= 500) return sum;\n i++;\n }\n return sum;\n }\n}\n// ----\n// f(uint256[]): 32, 3, 1000, 1, 2 -> 3\n// f(uint256[]): 32, 3, 100, 500, 300 -> 600\n// f(uint256[]): 32, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 111 -> 55\n" + }, + "member_accessors.sol": { + "content": "contract test {\n uint256 public data;\n bytes6 public name;\n bytes32 public a_hash;\n address public an_address;\n constructor() {\n data = 8;\n name = \"Celina\";\n a_hash = keccak256(\"\\x7b\");\n an_address = address(0x1337);\n super_secret_data = 42;\n }\n uint256 super_secret_data;\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// data() -> 8\n// name() -> \"Celina\"\n// a_hash() -> 0xa91eddf639b0b768929589c1a9fd21dcb0107199bdd82e55c5348018a1572f52\n// an_address() -> 0x1337\n// super_secret_data() -> FAILURE\n" + }, + "calling_nonexisting_contract_throws.sol": { + "content": "abstract contract D {\n function g() public virtual;\n}\n\n\ncontract C {\n D d = D(address(0x1212));\n\n function f() public returns (uint256) {\n d.g();\n return 7;\n }\n\n function g() public returns (uint256) {\n d.g{gas: 200}();\n return 7;\n }\n\n function h() public returns (uint256) {\n address(d).call(\"\"); // this does not throw (low-level)\n return 7;\n }\n}\n// ----\n// f() -> FAILURE\n// g() -> FAILURE\n// h() -> 7\n" + }, + "call_attached_library_function_on_string.sol": { + "content": "library D { function length(string memory self) public returns (uint) { return bytes(self).length; } }\ncontract C {\n using D for string;\n string x;\n function f() public returns (uint) {\n x = \"abc\";\n return x.length();\n }\n function g() public returns (uint) {\n string memory s = \"abc\";\n return s.length();\n }\n}\n// ----\n// library: D\n// f() -> 3\n// g() -> 3\n" + }, + "creation_function_call_with_salt.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C{salt: \"abc\"}(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 139112\n// gas irOptimized code: 53800\n// gas legacy: 145935\n// gas legacy code: 95600\n// gas legacyOptimized: 138529\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "multiple_functions.sol": { + "content": "contract test {\n function a() public returns(uint n) { return 0; }\n function b() public returns(uint n) { return 1; }\n function c() public returns(uint n) { return 2; }\n function f() public returns(uint n) { return 3; }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// a() -> 0\n// b() -> 1\n// c() -> 2\n// f() -> 3\n// i_am_not_there() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values.sol b/examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values.sol new file mode 100644 index 00000000..cb2a8a0c --- /dev/null +++ b/examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values.sol @@ -0,0 +1,7 @@ +contract test { + function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) { + y1 = x2; y2 = x1; + } +} +// ---- +// run(bool,uint256): true, 0xcd -> 0xcd, true, 0 diff --git a/examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values_standard_input.json b/examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values_standard_input.json new file mode 100644 index 00000000..14f12aca --- /dev/null +++ b/examples/test/semanticTests/functionCall_multiple_return_values/multiple_return_values_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_named_args/named_args.sol b/examples/test/semanticTests/functionCall_named_args/named_args.sol new file mode 100644 index 00000000..706f6d94 --- /dev/null +++ b/examples/test/semanticTests/functionCall_named_args/named_args.sol @@ -0,0 +1,8 @@ +contract test { + function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); } + function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); } +} +// ---- +// b() -> 123 +// c() -> 123 diff --git a/examples/test/semanticTests/functionCall_named_args/named_args_standard_input.json b/examples/test/semanticTests/functionCall_named_args/named_args_standard_input.json new file mode 100644 index 00000000..ac2dab40 --- /dev/null +++ b/examples/test/semanticTests/functionCall_named_args/named_args_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_named_args_overload/named_args_overload.sol b/examples/test/semanticTests/functionCall_named_args_overload/named_args_overload.sol new file mode 100644 index 00000000..65f34d8f --- /dev/null +++ b/examples/test/semanticTests/functionCall_named_args_overload/named_args_overload.sol @@ -0,0 +1,35 @@ +contract C { + function f() public returns (uint) { + return 0; + } + function f(uint a) public returns (uint) { + return a; + } + function f(uint a, uint b) public returns (uint) { + return a+b; + } + function f(uint a, uint b, uint c) public returns (uint) { + return a+b+c; + } + function call(uint num) public returns (uint256) { + if (num == 0) + return f(); + if (num == 1) + return f({a: 1}); + if (num == 2) + return f({b: 1, a: 2}); + if (num == 3) + return f({c: 1, a: 2, b: 3}); + if (num == 4) + return f({b: 5, c: 1, a: 2}); + + return 500; + } +} +// ---- +// call(uint256): 0 -> 0 +// call(uint256): 1 -> 1 +// call(uint256): 2 -> 3 +// call(uint256): 3 -> 6 +// call(uint256): 4 -> 8 +// call(uint256): 5 -> 500 diff --git a/examples/test/semanticTests/functionCall_named_args_overload/named_args_overload_standard_input.json b/examples/test/semanticTests/functionCall_named_args_overload/named_args_overload_standard_input.json new file mode 100644 index 00000000..42cb6d81 --- /dev/null +++ b/examples/test/semanticTests/functionCall_named_args_overload/named_args_overload_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + }, + "external_function.sol": { + "content": "contract c {\n function f(uint256 a) public returns (uint256) {\n return a;\n }\n\n function test(uint256 a, uint256 b)\n external\n returns (uint256 r_a, uint256 r_b)\n {\n r_a = f(a + 7);\n r_b = b;\n }\n}\n// ----\n// test(uint256,uint256): 2, 3 -> 9, 3\n" + }, + "creation_function_call_no_args.sol": { + "content": "contract C {\n uint public i;\n constructor() {\n i = 2;\n }\n}\ncontract D {\n function f() public returns (uint r) {\n return new C().i();\n }\n}\n// ----\n// f() -> 2\n// gas legacy: 76585\n// gas legacy code: 23600\n" + }, + "call_attached_library_function_on_storage_variable.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return (x.mul)({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "call_options_overload.sol": { + "content": "contract C {\n function f(uint x) external payable returns (uint) { return 1; }\n function f(uint x, uint y) external payable returns (uint) { return 2; }\n function call() public payable returns (uint v, uint x, uint y, uint z) {\n v = this.f{value: 10}(2);\n x = this.f{gas: 10000}(2, 3);\n y = this.f{gas: 10000, value: 10}(2, 3);\n z = this.f{value: 10, gas: 10000}(2, 3);\n }\n function bal() external returns (uint) { return address(this).balance; }\n receive() external payable {}\n}\n// ----\n// (), 1 ether\n// call() -> 1, 2, 2, 2\n// bal() -> 1000000000000000000\n" + }, + "mapping_array_internal_argument.sol": { + "content": "contract test {\n mapping(uint8 => uint8)[2] a;\n mapping(uint8 => uint8)[2] b;\n function set_internal(mapping(uint8 => uint8)[2] storage m, uint8 key, uint8 value1, uint8 value2) internal returns (uint8, uint8) {\n uint8 oldValue1 = m[0][key];\n uint8 oldValue2 = m[1][key];\n m[0][key] = value1;\n m[1][key] = value2;\n return (oldValue1, oldValue2);\n }\n function set(uint8 key, uint8 value_a1, uint8 value_a2, uint8 value_b1, uint8 value_b2) public returns (uint8 old_a1, uint8 old_a2, uint8 old_b1, uint8 old_b2) {\n (old_a1, old_a2) = set_internal(a, key, value_a1, value_a2);\n (old_b1, old_b2) = set_internal(b, key, value_b1, value_b2);\n }\n function get(uint8 key) public returns (uint8, uint8, uint8, uint8) {\n return (a[0][key], a[1][key], b[0][key], b[1][key]);\n }\n}\n// ----\n// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0\n// gas irOptimized: 111237\n// gas legacy: 113742\n// gas legacyOptimized: 111768\n// get(uint8): 1 -> 21, 22, 42, 43\n// set(uint8,uint8,uint8,uint8,uint8): 1, 10, 30, 11, 31 -> 21, 22, 42, 43\n// get(uint8): 1 -> 10, 30, 11, 31\n" + }, + "named_args_overload.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return 0;\n }\n function f(uint a) public returns (uint) {\n return a;\n }\n function f(uint a, uint b) public returns (uint) {\n return a+b;\n }\n function f(uint a, uint b, uint c) public returns (uint) {\n return a+b+c;\n }\n function call(uint num) public returns (uint256) {\n if (num == 0)\n return f();\n if (num == 1)\n return f({a: 1});\n if (num == 2)\n return f({b: 1, a: 2});\n if (num == 3)\n return f({c: 1, a: 2, b: 3});\n if (num == 4)\n return f({b: 5, c: 1, a: 2});\n\n return 500;\n }\n}\n// ----\n// call(uint256): 0 -> 0\n// call(uint256): 1 -> 1\n// call(uint256): 2 -> 3\n// call(uint256): 3 -> 6\n// call(uint256): 4 -> 8\n// call(uint256): 5 -> 500\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check.sol b/examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check.sol new file mode 100644 index 00000000..beda5f9b --- /dev/null +++ b/examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check.sol @@ -0,0 +1,33 @@ +interface Identity { + function selectorAndAppendValue(uint value) external pure returns (uint); +} +interface ReturnMoreData { + function f(uint value) external pure returns (uint, uint, uint); +} +contract C { + Identity constant i = Identity(address(0x0004)); + function testHighLevel() external pure returns (bool) { + // Works because the extcodesize check is skipped + // and the precompiled contract returns actual data. + i.selectorAndAppendValue(5); + return true; + } + function testHighLevel2() external pure returns (uint, uint, uint) { + // Fails because the identity contract does not return enough data. + return ReturnMoreData(address(4)).f(2); + } + function testLowLevel() external view returns (uint value) { + (bool success, bytes memory ret) = + address(4).staticcall( + abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5)) + ); + value = abi.decode(ret, (uint)); + } + +} +// ==== +// EVMVersion: >=constantinople +// ---- +// testHighLevel() -> true +// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000 +// testHighLevel2() -> FAILURE diff --git a/examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check_standard_input.json b/examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check_standard_input.json new file mode 100644 index 00000000..af5086b9 --- /dev/null +++ b/examples/test/semanticTests/functionCall_precompile_extcodesize_check/precompile_extcodesize_check_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected.sol b/examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected.sol new file mode 100644 index 00000000..c7a1d12b --- /dev/null +++ b/examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected.sol @@ -0,0 +1,31 @@ +interface ShortReturn { + function f() external pure returns (bytes32); +} +contract LongReturn { + function f() external pure returns (uint[20] memory) {} +} + +contract Test { + function test() public returns (uint) { + LongReturn longReturn = new LongReturn(); + uint freeMemoryBefore; + assembly { + freeMemoryBefore := mload(0x40) + } + + ShortReturn(address(longReturn)).f(); + + uint freeMemoryAfter; + + assembly { + freeMemoryAfter := mload(0x40) + } + + return freeMemoryAfter - freeMemoryBefore; + } +} +// ==== +// compileViaYul: true +// ---- +// test() -> 0x20 +// gas legacy: 131966 diff --git a/examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected_standard_input.json b/examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected_standard_input.json new file mode 100644 index 00000000..536f0031 --- /dev/null +++ b/examples/test/semanticTests/functionCall_return_size_bigger_than_expected/return_size_bigger_than_expected_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected.sol b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected.sol new file mode 100644 index 00000000..5f39b877 --- /dev/null +++ b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected.sol @@ -0,0 +1,32 @@ +interface LongReturn { + function f() external pure returns (uint[20] memory); +} +contract ShortReturn { + function f() external pure returns (bytes32) {} +} + +contract Test { + function test() public returns (uint) { + ShortReturn shortReturn = new ShortReturn(); + uint freeMemoryBefore; + assembly { + freeMemoryBefore := mload(0x40) + } + + LongReturn(address(shortReturn)).f(); + + uint freeMemoryAfter; + + assembly { + freeMemoryAfter := mload(0x40) + } + + return freeMemoryAfter - freeMemoryBefore; + } +} +// ==== +// EVMVersion: <=homestead +// compileViaYul: true +// ---- +// test() -> 0x0500 +// gas legacy: 131966 diff --git a/examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected_standard_input.json b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected_standard_input.json new file mode 100644 index 00000000..26e69e6c --- /dev/null +++ b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected/return_size_shorter_than_expected_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead.sol b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead.sol new file mode 100644 index 00000000..22583227 --- /dev/null +++ b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead.sol @@ -0,0 +1,34 @@ +interface LongReturn { + function f() external pure returns (uint[20] memory); +} +contract ShortReturn { + function f() external pure returns (bytes32) {} +} + +contract Test { + function test() public returns (uint) { + ShortReturn shortReturn = new ShortReturn(); + uint freeMemoryBefore; + assembly { + freeMemoryBefore := mload(0x40) + } + + // This reverts. The external call succeeds but ABI decoding fails due to the returned + // `bytes32` being much shorter than the expected `uint[20]`. + LongReturn(address(shortReturn)).f(); + + uint freeMemoryAfter; + + assembly { + freeMemoryAfter := mload(0x40) + } + + return freeMemoryAfter - freeMemoryBefore; + } +} +// ==== +// EVMVersion: >homestead +// compileViaYul: true +// ---- +// test() -> FAILURE +// gas legacy: 131966 diff --git a/examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead_standard_input.json b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead_standard_input.json new file mode 100644 index 00000000..3aecbfbd --- /dev/null +++ b/examples/test/semanticTests/functionCall_return_size_shorter_than_expected_evm_version_after_homestead/return_size_shorter_than_expected_evm_version_after_homestead_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "calling_uninitialized_function.sol": { + "content": "contract C {\n function intern() public returns (uint256) {\n function (uint) internal returns (uint) x;\n x(2);\n return 7;\n }\n\n function extern() public returns (uint256) {\n function (uint) external returns (uint) x;\n x(2);\n return 7;\n }\n}\n// ----\n// intern() -> FAILURE, hex\"4e487b71\", 0x51 # This should throw exceptions #\n// extern() -> FAILURE\n" + }, + "return_size_shorter_than_expected_evm_version_after_homestead.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n // This reverts. The external call succeeds but ABI decoding fails due to the returned\n // `bytes32` being much shorter than the expected `uint[20]`.\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: >homestead\n// compileViaYul: true\n// ----\n// test() -> FAILURE\n// gas legacy: 131966\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether.sol b/examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether.sol new file mode 100644 index 00000000..94a72132 --- /dev/null +++ b/examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether.sol @@ -0,0 +1,22 @@ +// Sending zero ether to a contract should still invoke the receive ether function +// (it previously did not because the gas stipend was not provided by the EVM) +contract Receiver { + receive() external payable {} +} + + +contract Main { + constructor() payable {} + + function s() public returns (bool) { + Receiver r = new Receiver(); + return payable(r).send(0); + } +} +// ---- +// constructor(), 20 wei -> +// gas irOptimized: 100264 +// gas legacy: 57555 +// gas legacy code: 53000 +// gas legacyOptimized: 100361 +// s() -> true diff --git a/examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether_standard_input.json b/examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether_standard_input.json new file mode 100644 index 00000000..880bcf66 --- /dev/null +++ b/examples/test/semanticTests/functionCall_send_zero_ether/send_zero_ether_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_transaction_status/transaction_status.sol b/examples/test/semanticTests/functionCall_transaction_status/transaction_status.sol new file mode 100644 index 00000000..caa538de --- /dev/null +++ b/examples/test/semanticTests/functionCall_transaction_status/transaction_status.sol @@ -0,0 +1,9 @@ +contract test { + function f() public { } + function g() public { revert(); } + function h() public { assert(false); } +} +// ---- +// f() -> +// g() -> FAILURE +// h() -> FAILURE, hex"4e487b71", 0x01 diff --git a/examples/test/semanticTests/functionCall_transaction_status/transaction_status_standard_input.json b/examples/test/semanticTests/functionCall_transaction_status/transaction_status_standard_input.json new file mode 100644 index 00000000..05fca895 --- /dev/null +++ b/examples/test/semanticTests/functionCall_transaction_status/transaction_status_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + }, + "precompile_extcodesize_check.sol": { + "content": "interface Identity {\n function selectorAndAppendValue(uint value) external pure returns (uint);\n}\ninterface ReturnMoreData {\n function f(uint value) external pure returns (uint, uint, uint);\n}\ncontract C {\n Identity constant i = Identity(address(0x0004));\n function testHighLevel() external pure returns (bool) {\n // Works because the extcodesize check is skipped\n // and the precompiled contract returns actual data.\n i.selectorAndAppendValue(5);\n return true;\n }\n function testHighLevel2() external pure returns (uint, uint, uint) {\n // Fails because the identity contract does not return enough data.\n return ReturnMoreData(address(4)).f(2);\n }\n function testLowLevel() external view returns (uint value) {\n (bool success, bytes memory ret) =\n address(4).staticcall(\n abi.encodeWithSelector(Identity.selectorAndAppendValue.selector, uint(5))\n );\n value = abi.decode(ret, (uint));\n }\n\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// testHighLevel() -> true\n// testLowLevel() -> 0xc76596d400000000000000000000000000000000000000000000000000000000\n// testHighLevel2() -> FAILURE\n" + }, + "return_size_bigger_than_expected.sol": { + "content": "interface ShortReturn {\n function f() external pure returns (bytes32);\n}\ncontract LongReturn {\n function f() external pure returns (uint[20] memory) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n LongReturn longReturn = new LongReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n ShortReturn(address(longReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0x20\n// gas legacy: 131966\n" + }, + "call_function_returning_function.sol": { + "content": "contract test {\n function f0() public returns (uint) {\n return 2;\n }\n\n function f1() internal returns (function() internal returns (uint)) {\n return f0;\n }\n\n function f2() internal returns (function() internal returns (function () internal returns (uint))) {\n return f1;\n }\n\n function f3() internal returns (function() internal returns (function () internal returns (function () internal returns (uint)))) {\n return f2;\n }\n\n function f() public returns (uint) {\n function() internal returns(function() internal returns(function() internal returns(function() internal returns(uint)))) x;\n x = f3;\n return x()()()();\n }\n}\n// ----\n// f() -> 2\n" + }, + "delegatecall_return_value.sol": { + "content": "contract C {\n uint256 value;\n\n function set(uint256 _value) external {\n value = _value;\n }\n\n function get() external view returns (uint256) {\n return value;\n }\n\n function get_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"get()\"));\n }\n\n function assert0() external view {\n assert(value == 0);\n }\n\n function assert0_delegated() external returns (bool, bytes memory) {\n return address(this).delegatecall(abi.encodeWithSignature(\"assert0()\"));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get() -> 0x00\n// assert0_delegated() -> 0x01, 0x40, 0x0\n// get_delegated() -> 0x01, 0x40, 0x20, 0x0\n// set(uint256): 0x01 ->\n// get() -> 0x01\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x1\n// set(uint256): 0x2a ->\n// get() -> 0x2a\n// assert0_delegated() -> 0x00, 0x40, 0x24, 0x4e487b7100000000000000000000000000000000000000000000000000000000, 0x0100000000000000000000000000000000000000000000000000000000\n// get_delegated() -> 0x01, 0x40, 0x20, 0x2a\n" + }, + "external_public_override.sol": { + "content": "contract A {\n function f() external virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return f();\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n" + }, + "external_call.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function g(uint n) external pure returns (uint) {\n return n + 1;\n }\n\n function f(uint n) public view returns (uint) {\n return this.g(2 * n);\n }\n}\n// ----\n// g(uint256): 4 -> 5\n// f(uint256): 2 -> 5\n" + }, + "transaction_status.sol": { + "content": "contract test {\n\tfunction f() public { }\n\tfunction g() public { revert(); }\n\tfunction h() public { assert(false); }\n}\n// ----\n// f() ->\n// g() -> FAILURE\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionCall_value_test/value_test.sol b/examples/test/semanticTests/functionCall_value_test/value_test.sol new file mode 100644 index 00000000..a6fea6a5 --- /dev/null +++ b/examples/test/semanticTests/functionCall_value_test/value_test.sol @@ -0,0 +1,8 @@ +contract C { + function f() public payable returns (uint) { + return msg.value; + } +} +// ---- +// f(), 1 ether -> 1000000000000000000 +// f(), 1 wei -> 1 diff --git a/examples/test/semanticTests/functionCall_value_test/value_test_standard_input.json b/examples/test/semanticTests/functionCall_value_test/value_test_standard_input.json new file mode 100644 index 00000000..84f4f24a --- /dev/null +++ b/examples/test/semanticTests/functionCall_value_test/value_test_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "external_call_dynamic_returndata.sol": { + "content": "pragma solidity >= 0.6.0;\n\ncontract C {\n function d(uint n) external pure returns (uint[] memory) {\n uint[] memory data = new uint[](n);\n for (uint i = 0; i < data.length; ++i)\n data[i] = i;\n return data;\n }\n\n function dt(uint n) public view returns (uint) {\n uint[] memory data = this.d(n);\n uint sum = 0;\n for (uint i = 0; i < data.length; ++i)\n sum += data[i];\n return sum;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// dt(uint256): 4 -> 6\n" + }, + "external_call_to_nonexisting_debugstrings.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 98698\n// gas irOptimized code: 284200\n// gas legacy: 123258\n// gas legacy code: 682400\n// gas legacyOptimized: 106969\n// gas legacyOptimized code: 386400\n// f(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 2 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 3 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 4 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 5 -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n// f(uint256): 6 -> 7\n" + }, + "return_size_shorter_than_expected.sol": { + "content": "interface LongReturn {\n function f() external pure returns (uint[20] memory);\n}\ncontract ShortReturn {\n function f() external pure returns (bytes32) {}\n}\n\ncontract Test {\n function test() public returns (uint) {\n ShortReturn shortReturn = new ShortReturn();\n uint freeMemoryBefore;\n assembly {\n freeMemoryBefore := mload(0x40)\n }\n\n LongReturn(address(shortReturn)).f();\n\n uint freeMemoryAfter;\n\n assembly {\n freeMemoryAfter := mload(0x40)\n }\n\n return freeMemoryAfter - freeMemoryBefore;\n }\n}\n// ====\n// EVMVersion: <=homestead\n// compileViaYul: true\n// ----\n// test() -> 0x0500\n// gas legacy: 131966\n" + }, + "multiple_return_values.sol": { + "content": "contract test {\n function run(bool x1, uint x2) public returns(uint y1, bool y2, uint y3) {\n y1 = x2; y2 = x1;\n }\n}\n// ----\n// run(bool,uint256): true, 0xcd -> 0xcd, true, 0\n" + }, + "call_attached_library_function_on_function.sol": { + "content": "library L {\n function g(function() internal returns (uint) _t) internal returns (uint) { return _t(); }\n}\ncontract C {\n using L for *;\n function f() public returns (uint) {\n return t.g();\n }\n function t() public pure returns (uint) { return 7; }\n}\n// ----\n// library: L\n// f() -> 7\n" + }, + "send_zero_ether.sol": { + "content": "// Sending zero ether to a contract should still invoke the receive ether function\n// (it previously did not because the gas stipend was not provided by the EVM)\ncontract Receiver {\n receive() external payable {}\n}\n\n\ncontract Main {\n constructor() payable {}\n\n function s() public returns (bool) {\n Receiver r = new Receiver();\n return payable(r).send(0);\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 100264\n// gas legacy: 57555\n// gas legacy code: 53000\n// gas legacyOptimized: 100361\n// s() -> true\n" + }, + "creation_function_call_with_args.sol": { + "content": "contract C {\n uint public i;\n constructor(uint newI) {\n i = newI;\n }\n}\ncontract D {\n C c;\n constructor(uint v) {\n c = new C(v);\n }\n function f() public returns (uint r) {\n return c.i();\n }\n}\n// ----\n// constructor(): 2 ->\n// gas irOptimized: 138930\n// gas irOptimized code: 53800\n// gas legacy: 145569\n// gas legacy code: 95600\n// gas legacyOptimized: 138297\n// gas legacyOptimized code: 54600\n// f() -> 2\n" + }, + "call_function_returning_nothing_via_pointer.sol": { + "content": "contract test {\n bool public flag = false;\n\n function f0() public {\n flag = true;\n }\n\n function f() public returns (bool) {\n function() internal x = f0;\n x();\n return flag;\n }\n}\n// ----\n// f() -> true\n// flag() -> true\n" + }, + "external_call_to_nonexisting.sol": { + "content": "// This tests skipping the extcodesize check.\n\ninterface I {\n function a() external pure;\n function b() external;\n function c() external payable;\n function x() external returns (uint);\n function y() external returns (string memory);\n}\ncontract C {\n I i = I(address(0xcafecafe));\n constructor() payable {}\n function f(uint c) external returns (uint) {\n if (c == 0) i.a();\n else if (c == 1) i.b();\n else if (c == 2) i.c();\n else if (c == 3) i.c{value: 1}();\n else if (c == 4) i.x();\n else if (c == 5) i.y();\n return 1 + c;\n }\n}\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 88853\n// gas irOptimized code: 164400\n// gas legacy: 102721\n// gas legacy code: 334400\n// gas legacyOptimized: 91499\n// gas legacyOptimized code: 196400\n// f(uint256): 0 -> FAILURE\n// f(uint256): 1 -> FAILURE\n// f(uint256): 2 -> FAILURE\n// f(uint256): 3 -> FAILURE\n// f(uint256): 4 -> FAILURE\n// f(uint256): 5 -> FAILURE\n// f(uint256): 6 -> 7\n" + }, + "mapping_internal_return.sol": { + "content": "contract test {\n mapping(uint8 => uint8) a;\n mapping(uint8 => uint8) b;\n function f() internal returns (mapping(uint8 => uint8) storage r) {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 84;\n }\n function g() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n f()[2] = 21;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function h() public returns (uint8, uint8, uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = f();\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// g() -> 0, 42, 0, 0, 84, 21\n// h() -> 0, 42, 0, 0, 84, 17\n" + }, + "named_args.sol": { + "content": "contract test {\n function a(uint a, uint b, uint c) public returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n function b() public returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n function c() public returns (uint r) { r = a({b: 2, c: 3, a: 1}); }\n}\n// ----\n// b() -> 123\n// c() -> 123\n" + }, + "file_level_call_via_module.sol": { + "content": "==== Source: a.sol ====\nfunction f(uint) pure returns (uint) { return 7; }\nfunction f(bytes memory x) pure returns (uint) { return x.length; }\n==== Source: b.sol ====\nimport \"a.sol\" as M;\ncontract C {\n function f() public pure returns (uint, uint) {\n return (M.f(2), M.f(\"abc\"));\n\n }\n}\n// ----\n// f() -> 7, 3\n" + }, + "conditional_with_arguments.sol": { + "content": "contract C {\n function g(int x, int y) public pure returns (int) { return x - y; }\n function h(int y, int x) public pure returns (int) { return y - x; }\n\n function f() public pure returns (int) {\n return (false ? g : h)(2, 1);\n }\n}\n// ----\n// f() -> 1\n" + }, + "value_test.sol": { + "content": "contract C {\n\tfunction f() public payable returns (uint) {\n\t\treturn msg.value;\n\t}\n}\n// ----\n// f(), 1 ether -> 1000000000000000000\n// f(), 1 wei -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name.sol b/examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name.sol new file mode 100644 index 00000000..0a9e6d3f --- /dev/null +++ b/examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name.sol @@ -0,0 +1,20 @@ +contract A { + function f() external {} + function g(uint256) external {} +} +contract B { + function f() external returns (uint256) {} + function g(uint256) external returns (uint256) {} +} +contract C { + function test1() external returns(bytes4, bytes4, bytes4, bytes4) { + return (A.f.selector, A.g.selector, B.f.selector, B.g.selector); + } + function test2() external returns(bytes4, bytes4, bytes4, bytes4) { + A a; B b; + return (a.f.selector, a.g.selector, b.f.selector, b.g.selector); + } +} +// ---- +// test1() -> left(0x26121ff0), left(0xe420264a), left(0x26121ff0), left(0xe420264a) +// test2() -> left(0x26121ff0), left(0xe420264a), left(0x26121ff0), left(0xe420264a) diff --git a/examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name_standard_input.json b/examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name_standard_input.json new file mode 100644 index 00000000..8d4cf630 --- /dev/null +++ b/examples/test/semanticTests/functionSelector_function_selector_via_contract_name/function_selector_via_contract_name_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "function_selector_via_contract_name.sol": { + "content": "contract A {\n function f() external {}\n function g(uint256) external {}\n}\ncontract B {\n function f() external returns (uint256) {}\n function g(uint256) external returns (uint256) {}\n}\ncontract C {\n function test1() external returns(bytes4, bytes4, bytes4, bytes4) {\n return (A.f.selector, A.g.selector, B.f.selector, B.g.selector);\n }\n function test2() external returns(bytes4, bytes4, bytes4, bytes4) {\n A a; B b;\n return (a.f.selector, a.g.selector, b.f.selector, b.g.selector);\n }\n}\n// ----\n// test1() -> left(0x26121ff0), left(0xe420264a), left(0x26121ff0), left(0xe420264a)\n// test2() -> left(0x26121ff0), left(0xe420264a), left(0x26121ff0), left(0xe420264a)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_address_member/address_member.sol b/examples/test/semanticTests/functionTypes_address_member/address_member.sol new file mode 100644 index 00000000..a5f56f3d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_address_member/address_member.sol @@ -0,0 +1,10 @@ +contract C { + function f() public view returns (address a1, address a2) { + a1 = this.f.address; + this.f.address; + [this.f.address][0]; + a2 = [this.f.address][0]; + } +} +// ---- +// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e diff --git a/examples/test/semanticTests/functionTypes_address_member/address_member_standard_input.json b/examples/test/semanticTests/functionTypes_address_member/address_member_standard_input.json new file mode 100644 index 00000000..b73a484d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_address_member/address_member_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir.sol b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir.sol new file mode 100644 index 00000000..a083ee1d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir.sol @@ -0,0 +1,27 @@ +contract Other { + function addTwo(uint256 x) public returns (uint256) { + return x + 2; + } +} +contract C { + function (function (uint) external returns (uint)) internal returns (uint) ev; + function (uint) external returns (uint) x; + + function store(function(uint) external returns (uint) y) public { + x = y; + } + + function eval(function(uint) external returns (uint) y) public returns (uint) { + return y(7); + } + + function t() public returns (uint256) { + this.store((new Other()).addTwo); + // This call panics + return ev(x); + } +} +// ==== +// compileViaYul: true +// ---- +// t() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir_standard_input.json b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir_standard_input.json new file mode 100644 index 00000000..4b7a29b3 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_ir/call_to_zero_initialized_function_type_ir_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy.sol b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy.sol new file mode 100644 index 00000000..feca44e0 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy.sol @@ -0,0 +1,27 @@ +contract Other { + function addTwo(uint256 x) public returns (uint256) { + return x + 2; + } +} +contract C { + function (function (uint) external returns (uint)) internal returns (uint) ev; + function (uint) external returns (uint) x; + + function store(function(uint) external returns (uint) y) public { + x = y; + } + + function eval(function(uint) external returns (uint) y) public returns (uint) { + return y(7); + } + + function t() public returns (uint256) { + this.store((new Other()).addTwo); + // This call panics + return ev(x); + } +} +// ==== +// compileViaYul: false +// ---- +// t() -> FAILURE diff --git a/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy_standard_input.json b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy_standard_input.json new file mode 100644 index 00000000..a8c1303a --- /dev/null +++ b/examples/test/semanticTests/functionTypes_call_to_zero_initialized_function_type_legacy/call_to_zero_initialized_function_type_legacy_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits.sol b/examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits.sol new file mode 100644 index 00000000..da9c528f --- /dev/null +++ b/examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits.sol @@ -0,0 +1,16 @@ +contract C { + function g() external {} + function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) { + function() external g_ptr_dirty = this.g; + assembly { + g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1))) + g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1))) + } + function() external g_ptr = this.g; + return g_ptr == g_ptr_dirty; + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true diff --git a/examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits_standard_input.json b/examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits_standard_input.json new file mode 100644 index 00000000..72d64616 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_comparison_operator_for_external_function_cleans_dirty_bits/comparison_operator_for_external_function_cleans_dirty_bits_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions.sol b/examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions.sol new file mode 100644 index 00000000..6c47752c --- /dev/null +++ b/examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions.sol @@ -0,0 +1,79 @@ +contract C { + function f() external {} + function g() external {} + function h() pure external {} + function i() view external {} + + function comparison_operators_for_external_functions() public returns (bool) { + assert( + this.f != this.g && + this.f != this.h && + this.f != this.i && + + this.g != this.h && + this.g != this.i && + + this.h != this.i && + + this.f == this.f && + this.g == this.g && + this.h == this.h && + this.i == this.i + ); + return true; + } + + function comparison_operators_for_local_external_function_pointers() public returns (bool) { + function () external f_local = this.f; + function () external g_local = this.g; + function () external pure h_local = this.h; + function () external view i_local = this.i; + + assert( + f_local == this.f && + g_local == this.g && + h_local == this.h && + i_local == this.i && + + f_local != this.g && + f_local != this.h && + f_local != this.i && + + g_local != this.f && + g_local != this.h && + g_local != this.i && + + h_local != this.f && + h_local != this.g && + h_local != this.i && + + i_local != this.f && + i_local != this.g && + i_local != this.h + ); + + assert( + f_local == f_local && + f_local != g_local && + f_local != h_local && + f_local != i_local + ); + + assert( + g_local == g_local && + g_local != h_local && + g_local != i_local + ); + + assert( + h_local == h_local && + i_local == i_local && + h_local != i_local + ); + + return true; + } +} +// ---- +// comparison_operators_for_external_functions() -> true +// comparison_operators_for_local_external_function_pointers() -> true diff --git a/examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions_standard_input.json b/examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions_standard_input.json new file mode 100644 index 00000000..88703d8a --- /dev/null +++ b/examples/test/semanticTests/functionTypes_comparison_operators_for_external_functions/comparison_operators_for_external_functions_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher.sol b/examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher.sol new file mode 100644 index 00000000..c15007c5 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher.sol @@ -0,0 +1,9 @@ +contract C { + function a() internal {} + function f() public { + function() ptr1 = a; + function() ptr2 = a; + } +} +// ---- +// f() diff --git a/examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher_standard_input.json b/examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher_standard_input.json new file mode 100644 index 00000000..400c9a41 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_duplicated_function_definition_with_same_id_in_internal_dispatcher/duplicated_function_definition_with_same_id_in_internal_dispatcher_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol b/examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol new file mode 100644 index 00000000..069d257f --- /dev/null +++ b/examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol @@ -0,0 +1,10 @@ +contract C { + function g(string calldata) external returns (bool) { return true; } + + function main() external returns (bool) { + function (string memory) external returns (bool) ptr = this.g; + return ptr("testString"); + } +} +// ---- +// main() -> true diff --git a/examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type_standard_input.json b/examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type_standard_input.json new file mode 100644 index 00000000..52c7f8f7 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type/external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "struct_with_external_function.sol": { + "content": "struct S {\n uint16 a;\n function() external returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() public pure returns (uint) {\n return 1;\n }\n\n function Y() public pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = this.Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = this.X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "pass_function_types_externally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return this.eval(this.g, x);\n }\n\n function f2(uint256 x) public returns (uint256) {\n return eval(this.g, x);\n }\n\n function eval(function(uint) external returns (uint) x, uint a) public returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n// f2(uint256): 7 -> 8\n" + }, + "same_function_in_construction_and_runtime.sol": { + "content": "contract C {\n uint256 public initial;\n\n constructor() {\n initial = double(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function runtime(uint256 _arg) public returns (uint256) {\n return double(_arg);\n }\n}\n// ----\n// runtime(uint256): 3 -> 6\n// initial() -> 4\n" + }, + "selector_ternary_function_pointer_from_function_call.sol": { + "content": "contract A {\n function f() public {}\n\tfunction g() public {}\n}\n\ncontract C {\n A a = new A();\n\n function getContract() public view returns (A) {\n return a;\n }\n\n function test(bool b) public view returns (bytes4) {\n return (b ? getContract().f : getContract().g).selector;\n }\n}\n// ----\n// test(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// test(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "store_function.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\n\n\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n ev = eval;\n this.store((new Other()).addTwo);\n return ev(x);\n }\n}\n// ----\n// t() -> 9\n// gas irOptimized: 99064\n// gas legacy: 79492\n// gas legacy code: 69600\n// gas legacyOptimized: 77587\n// gas legacyOptimized code: 28600\n" + }, + "external_functions_with_calldata_args_assigned_to_function_pointers_with_memory_type.sol": { + "content": "contract C {\n function g(string calldata) external returns (bool) { return true; }\n\n function main() external returns (bool) {\n function (string memory) external returns (bool) ptr = this.g;\n return ptr(\"testString\");\n }\n}\n// ----\n// main() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack.sol b/examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack.sol new file mode 100644 index 00000000..67a4434d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack.sol @@ -0,0 +1,13 @@ +contract C { + function a() public returns (uint256) { + return 7; + } + + function test() public returns (uint256) { + function() returns (uint256) y = a; + delete y; + y(); + } +} +// ---- +// test() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack_standard_input.json b/examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack_standard_input.json new file mode 100644 index 00000000..8aec827f --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_delete_stack/function_delete_stack_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage.sol b/examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage.sol new file mode 100644 index 00000000..a147b4e0 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage.sol @@ -0,0 +1,26 @@ +contract C { + function a() public returns (uint256) { + return 7; + } + + function() returns (uint256) internal y; + + function set() public returns (uint256) { + y = a; + return y(); + } + + function d() public returns (uint256) { + delete y; + return 1; + } + + function ca() public returns (uint256) { + return y(); + } +} +// ---- +// set() -> 7 +// ca() -> 7 +// d() -> 1 +// ca() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage_standard_input.json b/examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage_standard_input.json new file mode 100644 index 00000000..2829acd5 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_delete_storage/function_delete_storage_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage.sol b/examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage.sol new file mode 100644 index 00000000..d5e105e5 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage.sol @@ -0,0 +1,37 @@ +contract C { + function() external public x; + uint public y = 0; + + function increment() public { + ++y; + } + + function set() external { + x = this.increment; + } + + function incrementIndirectly() public { + x(); + } + + function deleteFunction() public { + // used to lead to an ICE during IR + delete x; + } +} +// ---- +// x() -> 0 +// y() -> 0 +// increment() -> +// y() -> 1 +// set() -> +// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000 +// increment() -> +// y() -> 2 +// incrementIndirectly() -> +// y() -> 3 +// deleteFunction() -> +// increment() -> +// y() -> 4 +// incrementIndirectly() -> FAILURE +// y() -> 4 diff --git a/examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage_standard_input.json b/examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage_standard_input.json new file mode 100644 index 00000000..42b2fb7a --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_external_delete_storage/function_external_delete_storage_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal.sol b/examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal.sol new file mode 100644 index 00000000..587daac9 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal.sol @@ -0,0 +1,25 @@ +library Utils { + function reduce( + uint256[] memory array, + function(uint, uint) internal returns (uint) f, + uint256 init + ) internal returns (uint256) { + for (uint256 i = 0; i < array.length; i++) { + init = f(array[i], init); + } + return init; + } + + function sum(uint256 a, uint256 b) internal returns (uint256) { + return a + b; + } +} + + +contract C { + function f(uint256[] memory x) public returns (uint256) { + return Utils.reduce(x, Utils.sum, 0); + } +} +// ---- +// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11 diff --git a/examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal_standard_input.json b/examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal_standard_input.json new file mode 100644 index 00000000..7cc82482 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_function_type_library_internal/function_type_library_internal_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option.sol b/examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option.sol new file mode 100644 index 00000000..e65da6e1 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option.sol @@ -0,0 +1,10 @@ +contract C { + function f() external payable returns (uint) { assert(msg.value > 0); return 1; } + function g() external payable returns (uint) { assert(msg.value > 0); return 2; } + + function h() public payable returns (uint) { + return [this.f, this.g][0]{value: 1}(); + } +} +// ---- +// h(), 1 ether -> 1 diff --git a/examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option_standard_input.json b/examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option_standard_input.json new file mode 100644 index 00000000..61f16d21 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_inline_array_with_value_call_option/inline_array_with_value_call_option_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions.sol b/examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions.sol new file mode 100644 index 00000000..f9cd863b --- /dev/null +++ b/examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions.sol @@ -0,0 +1,33 @@ +contract Flow { + bool public success; + + mapping(address => function() internal) stages; + + function stage0() internal { + stages[msg.sender] = stage1; + } + + function stage1() internal { + stages[msg.sender] = stage2; + } + + function stage2() internal { + success = true; + } + + constructor() { + stages[msg.sender] = stage0; + } + + function f() public returns (uint256) { + stages[msg.sender](); + return 7; + } +} +// ---- +// success() -> false +// f() -> 7 +// f() -> 7 +// success() -> false +// f() -> 7 +// success() -> true diff --git a/examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions_standard_input.json b/examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions_standard_input.json new file mode 100644 index 00000000..7df29604 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_mapping_of_functions/mapping_of_functions_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally.sol b/examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally.sol new file mode 100644 index 00000000..3f14eb59 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally.sol @@ -0,0 +1,20 @@ +contract C { + function f(uint256 x) public returns (uint256) { + return this.eval(this.g, x); + } + + function f2(uint256 x) public returns (uint256) { + return eval(this.g, x); + } + + function eval(function(uint) external returns (uint) x, uint a) public returns (uint) { + return x(a); + } + + function g(uint256 x) public returns (uint256) { + return x + 1; + } +} +// ---- +// f(uint256): 7 -> 8 +// f2(uint256): 7 -> 8 diff --git a/examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally_standard_input.json b/examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally_standard_input.json new file mode 100644 index 00000000..a552a156 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_pass_function_types_externally/pass_function_types_externally_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "struct_with_external_function.sol": { + "content": "struct S {\n uint16 a;\n function() external returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() public pure returns (uint) {\n return 1;\n }\n\n function Y() public pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = this.Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = this.X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "pass_function_types_externally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return this.eval(this.g, x);\n }\n\n function f2(uint256 x) public returns (uint256) {\n return eval(this.g, x);\n }\n\n function eval(function(uint) external returns (uint) x, uint a) public returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n// f2(uint256): 7 -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally.sol b/examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally.sol new file mode 100644 index 00000000..0acbcc58 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally.sol @@ -0,0 +1,15 @@ +contract C { + function f(uint256 x) public returns (uint256) { + return eval(g, x); + } + + function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) { + return x(a); + } + + function g(uint256 x) public pure returns (uint256) { + return x + 1; + } +} +// ---- +// f(uint256): 7 -> 8 diff --git a/examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally_standard_input.json b/examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally_standard_input.json new file mode 100644 index 00000000..1baa97f6 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_pass_function_types_internally/pass_function_types_internally_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime.sol b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime.sol new file mode 100644 index 00000000..84f6fad1 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime.sol @@ -0,0 +1,18 @@ +contract C { + uint256 public initial; + + constructor() { + initial = double(2); + } + + function double(uint256 _arg) public returns (uint256 _ret) { + _ret = _arg * 2; + } + + function runtime(uint256 _arg) public returns (uint256) { + return double(_arg); + } +} +// ---- +// runtime(uint256): 3 -> 6 +// initial() -> 4 diff --git a/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime_standard_input.json b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime_standard_input.json new file mode 100644 index 00000000..05f3049b --- /dev/null +++ b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime/same_function_in_construction_and_runtime_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "struct_with_external_function.sol": { + "content": "struct S {\n uint16 a;\n function() external returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() public pure returns (uint) {\n return 1;\n }\n\n function Y() public pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = this.Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = this.X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "pass_function_types_externally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return this.eval(this.g, x);\n }\n\n function f2(uint256 x) public returns (uint256) {\n return eval(this.g, x);\n }\n\n function eval(function(uint) external returns (uint) x, uint a) public returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n// f2(uint256): 7 -> 8\n" + }, + "same_function_in_construction_and_runtime.sol": { + "content": "contract C {\n uint256 public initial;\n\n constructor() {\n initial = double(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function runtime(uint256 _arg) public returns (uint256) {\n return double(_arg);\n }\n}\n// ----\n// runtime(uint256): 3 -> 6\n// initial() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check.sol b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check.sol new file mode 100644 index 00000000..b5b24954 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check.sol @@ -0,0 +1,17 @@ +contract C { + function(uint256) returns (uint256) internal x; + + constructor() { + x = double; + } + + function test() public returns (bool) { + return x == double; + } + + function double(uint256 _arg) public returns (uint256 _ret) { + _ret = _arg * 2; + } +} +// ---- +// test() -> true diff --git a/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check_standard_input.json b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check_standard_input.json new file mode 100644 index 00000000..f3e1072f --- /dev/null +++ b/examples/test/semanticTests/functionTypes_same_function_in_construction_and_runtime_equality_check/same_function_in_construction_and_runtime_equality_check_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_selector_1/selector_1.sol b/examples/test/semanticTests/functionTypes_selector_1/selector_1.sol new file mode 100644 index 00000000..397655da --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_1/selector_1.sol @@ -0,0 +1,14 @@ +contract B { + function ext() external {} + function pub() public {} +} + +contract C is B { + function test() public returns (bytes4, bytes4, bytes4, bytes4) { + return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector); + } +} +// ==== +// compileViaYul: true +// ---- +// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/functionTypes_selector_1/selector_1_standard_input.json b/examples/test/semanticTests/functionTypes_selector_1/selector_1_standard_input.json new file mode 100644 index 00000000..f829950d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_1/selector_1_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_selector_2/selector_2.sol b/examples/test/semanticTests/functionTypes_selector_2/selector_2.sol new file mode 100644 index 00000000..248e4467 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_2/selector_2.sol @@ -0,0 +1,14 @@ +contract B { + function ext() external {} + function pub() public {} +} + +contract D { + function test() public returns (bytes4, bytes4) { + return (B.ext.selector, B.pub.selector); + } +} +// ==== +// compileViaYul: true +// ---- +// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/functionTypes_selector_2/selector_2_standard_input.json b/examples/test/semanticTests/functionTypes_selector_2/selector_2_standard_input.json new file mode 100644 index 00000000..918b60d1 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_2/selector_2_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression.sol b/examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression.sol new file mode 100644 index 00000000..896dbeb9 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression.sol @@ -0,0 +1,10 @@ +contract C { + bool public z; + function f() public { + ((z = true) ? this.f : this.f).selector; + } +} + +// ---- +// f() +// z() -> true diff --git a/examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression_standard_input.json b/examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression_standard_input.json new file mode 100644 index 00000000..90428f01 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_assignment_expression/selector_assignment_expression_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect.sol b/examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect.sol new file mode 100644 index 00000000..cdb7b98d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect.sol @@ -0,0 +1,13 @@ +contract C { + uint x; + function f() public returns (uint256) { + h().f.selector; + return x; + } + function h() public returns (C) { + x = 42; + return this; + } +} +// ---- +// f() -> 42 diff --git a/examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect_standard_input.json b/examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect_standard_input.json new file mode 100644 index 00000000..b29a8312 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_expression_side_effect/selector_expression_side_effect_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary.sol b/examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary.sol new file mode 100644 index 00000000..567b7c14 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary.sol @@ -0,0 +1,10 @@ +contract C { + function f() public {} + function g() public {} + function h(bool c) public returns (bytes4) { + return (c ? this.f : this.g).selector; + } +} +// ---- +// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000 +// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary_standard_input.json b/examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary_standard_input.json new file mode 100644 index 00000000..8546d1da --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_ternary/selector_ternary_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call.sol b/examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call.sol new file mode 100644 index 00000000..83415f72 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call.sol @@ -0,0 +1,19 @@ +contract A { + function f() public {} + function g() public {} +} + +contract C { + A a = new A(); + + function getContract() public view returns (A) { + return a; + } + + function test(bool b) public view returns (bytes4) { + return (b ? getContract().f : getContract().g).selector; + } +} +// ---- +// test(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000 +// test(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call_standard_input.json b/examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call_standard_input.json new file mode 100644 index 00000000..05b8562e --- /dev/null +++ b/examples/test/semanticTests/functionTypes_selector_ternary_function_pointer_from_function_call/selector_ternary_function_pointer_from_function_call_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "struct_with_external_function.sol": { + "content": "struct S {\n uint16 a;\n function() external returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() public pure returns (uint) {\n return 1;\n }\n\n function Y() public pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = this.Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = this.X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "pass_function_types_externally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return this.eval(this.g, x);\n }\n\n function f2(uint256 x) public returns (uint256) {\n return eval(this.g, x);\n }\n\n function eval(function(uint) external returns (uint) x, uint a) public returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n// f2(uint256): 7 -> 8\n" + }, + "same_function_in_construction_and_runtime.sol": { + "content": "contract C {\n uint256 public initial;\n\n constructor() {\n initial = double(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function runtime(uint256 _arg) public returns (uint256) {\n return double(_arg);\n }\n}\n// ----\n// runtime(uint256): 3 -> 6\n// initial() -> 4\n" + }, + "selector_ternary_function_pointer_from_function_call.sol": { + "content": "contract A {\n function f() public {}\n\tfunction g() public {}\n}\n\ncontract C {\n A a = new A();\n\n function getContract() public view returns (A) {\n return a;\n }\n\n function test(bool b) public view returns (bytes4) {\n return (b ? getContract().f : getContract().g).selector;\n }\n}\n// ----\n// test(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// test(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function.sol b/examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function.sol new file mode 100644 index 00000000..f811988f --- /dev/null +++ b/examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function.sol @@ -0,0 +1,23 @@ +contract C { + function g() external {} + function h() external payable {} + function test_function() external returns (bool){ + assert ( + this.g.address == this.g.address && + this.g{gas: 42}.address == this.g.address && + this.g{gas: 42}.selector == this.g.selector + ); + assert ( + this.h.address == this.h.address && + this.h{gas: 42}.address == this.h.address && + this.h{gas: 42}.selector == this.h.selector + ); + assert ( + this.h{gas: 42, value: 5}.address == this.h.address && + this.h{gas: 42, value: 5}.selector == this.h.selector + ); + return true; + } +} +// ---- +// test_function() -> true diff --git a/examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function_standard_input.json b/examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function_standard_input.json new file mode 100644 index 00000000..b118fb4f --- /dev/null +++ b/examples/test/semanticTests/functionTypes_stack_height_check_on_adding_gas_variable_to_function/stack_height_check_on_adding_gas_variable_to_function_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_store_function/store_function.sol b/examples/test/semanticTests/functionTypes_store_function/store_function.sol new file mode 100644 index 00000000..eeab740a --- /dev/null +++ b/examples/test/semanticTests/functionTypes_store_function/store_function.sol @@ -0,0 +1,32 @@ +contract Other { + function addTwo(uint256 x) public returns (uint256) { + return x + 2; + } +} + + +contract C { + function (function (uint) external returns (uint)) internal returns (uint) ev; + function (uint) external returns (uint) x; + + function store(function(uint) external returns (uint) y) public { + x = y; + } + + function eval(function(uint) external returns (uint) y) public returns (uint) { + return y(7); + } + + function t() public returns (uint256) { + ev = eval; + this.store((new Other()).addTwo); + return ev(x); + } +} +// ---- +// t() -> 9 +// gas irOptimized: 99064 +// gas legacy: 79492 +// gas legacy code: 69600 +// gas legacyOptimized: 77587 +// gas legacyOptimized code: 28600 diff --git a/examples/test/semanticTests/functionTypes_store_function/store_function_standard_input.json b/examples/test/semanticTests/functionTypes_store_function/store_function_standard_input.json new file mode 100644 index 00000000..e4cf93ed --- /dev/null +++ b/examples/test/semanticTests/functionTypes_store_function/store_function_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "struct_with_external_function.sol": { + "content": "struct S {\n uint16 a;\n function() external returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() public pure returns (uint) {\n return 1;\n }\n\n function Y() public pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = this.Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = this.X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "pass_function_types_externally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return this.eval(this.g, x);\n }\n\n function f2(uint256 x) public returns (uint256) {\n return eval(this.g, x);\n }\n\n function eval(function(uint) external returns (uint) x, uint a) public returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n// f2(uint256): 7 -> 8\n" + }, + "same_function_in_construction_and_runtime.sol": { + "content": "contract C {\n uint256 public initial;\n\n constructor() {\n initial = double(2);\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n\n function runtime(uint256 _arg) public returns (uint256) {\n return double(_arg);\n }\n}\n// ----\n// runtime(uint256): 3 -> 6\n// initial() -> 4\n" + }, + "selector_ternary_function_pointer_from_function_call.sol": { + "content": "contract A {\n function f() public {}\n\tfunction g() public {}\n}\n\ncontract C {\n A a = new A();\n\n function getContract() public view returns (A) {\n return a;\n }\n\n function test(bool b) public view returns (bytes4) {\n return (b ? getContract().f : getContract().g).selector;\n }\n}\n// ----\n// test(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// test(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "store_function.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\n\n\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n ev = eval;\n this.store((new Other()).addTwo);\n return ev(x);\n }\n}\n// ----\n// t() -> 9\n// gas irOptimized: 99064\n// gas legacy: 79492\n// gas legacy code: 69600\n// gas legacyOptimized: 77587\n// gas legacyOptimized code: 28600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function.sol b/examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function.sol new file mode 100644 index 00000000..3de9cfa8 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function.sol @@ -0,0 +1,31 @@ +struct S { + uint16 a; + function() external returns (uint) x; + uint16 b; +} +contract Flow { + S[2] t; + + function X() public pure returns (uint) { + return 1; + } + + function Y() public pure returns (uint) { + return 2; + } + + constructor() { + t[0].a = 0xff07; + t[0].b = 0xff07; + t[1].x = this.Y; + t[1].a = 0xff07; + t[1].b = 0xff07; + t[0].x = this.X; + } + + function f() public returns (uint, uint) { + return (t[0].x(), t[1].x()); + } +} +// ---- +// f() -> 1, 2 diff --git a/examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function_standard_input.json b/examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function_standard_input.json new file mode 100644 index 00000000..7fd7cba4 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_struct_with_external_function/struct_with_external_function_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "call_to_zero_initialized_function_type_legacy.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// t() -> FAILURE\n" + }, + "call_to_zero_initialized_function_type_ir.sol": { + "content": "contract Other {\n function addTwo(uint256 x) public returns (uint256) {\n return x + 2;\n }\n}\ncontract C {\n function (function (uint) external returns (uint)) internal returns (uint) ev;\n function (uint) external returns (uint) x;\n\n function store(function(uint) external returns (uint) y) public {\n x = y;\n }\n\n function eval(function(uint) external returns (uint) y) public returns (uint) {\n return y(7);\n }\n\n function t() public returns (uint256) {\n this.store((new Other()).addTwo);\n // This call panics\n return ev(x);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// t() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "struct_with_external_function.sol": { + "content": "struct S {\n uint16 a;\n function() external returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() public pure returns (uint) {\n return 1;\n }\n\n function Y() public pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = this.Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = this.X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions.sol b/examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions.sol new file mode 100644 index 00000000..fae91862 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions.sol @@ -0,0 +1,31 @@ +struct S { + uint16 a; + function() returns (uint) x; + uint16 b; +} +contract Flow { + S[2] t; + + function X() internal pure returns (uint) { + return 1; + } + + function Y() internal pure returns (uint) { + return 2; + } + + constructor() { + t[0].a = 0xff07; + t[0].b = 0xff07; + t[1].x = Y; + t[1].a = 0xff07; + t[1].b = 0xff07; + t[0].x = X; + } + + function f() public returns (uint, uint) { + return (t[0].x(), t[1].x()); + } +} +// ---- +// f() -> 1, 2 diff --git a/examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions_standard_input.json b/examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions_standard_input.json new file mode 100644 index 00000000..449fe2f4 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_struct_with_functions/struct_with_functions_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function.sol b/examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function.sol new file mode 100644 index 00000000..f7dc8904 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function.sol @@ -0,0 +1,10 @@ +contract C { + function f() internal pure returns(uint256) { return 1;} + function g() internal pure returns(uint256) { return 2; } + function test(bool b) public returns(uint256) { + return (b ? C.f : C.g)(); + } +} +// ---- +// test(bool): true -> 1 +// test(bool): false -> 2 diff --git a/examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function_standard_input.json b/examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function_standard_input.json new file mode 100644 index 00000000..3bc10465 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_ternary_contract_internal_function/ternary_contract_internal_function_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function.sol b/examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function.sol new file mode 100644 index 00000000..a29a678d --- /dev/null +++ b/examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function.sol @@ -0,0 +1,13 @@ +library L { + function f() internal pure returns(uint256){ return 1; } +} + +contract C { + function g() internal pure returns(uint256) { return 2; } + function test(bool b) public returns(uint256) { + return (b ? L.f : C.g)(); + } +} +// ---- +// test(bool): true -> 1 +// test(bool): false -> 2 diff --git a/examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function_standard_input.json b/examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function_standard_input.json new file mode 100644 index 00000000..aa1db8b7 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_ternary_contract_library_internal_function/ternary_contract_library_internal_function_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "selector_expression_side_effect.sol": { + "content": "contract C {\n\tuint x;\n\tfunction f() public returns (uint256) {\n\t\th().f.selector;\n\t\treturn x;\n\t}\n\tfunction h() public returns (C) {\n\t\tx = 42;\n\t\treturn this;\n\t}\n}\n// ----\n// f() -> 42\n" + }, + "same_function_in_construction_and_runtime_equality_check.sol": { + "content": "contract C {\n function(uint256) returns (uint256) internal x;\n\n constructor() {\n x = double;\n }\n\n function test() public returns (bool) {\n return x == double;\n }\n\n function double(uint256 _arg) public returns (uint256 _ret) {\n _ret = _arg * 2;\n }\n}\n// ----\n// test() -> true\n" + }, + "ternary_contract_library_internal_function.sol": { + "content": "library L {\n function f() internal pure returns(uint256){ return 1; }\n}\n\ncontract C {\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? L.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function.sol b/examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function.sol new file mode 100644 index 00000000..6d52017a --- /dev/null +++ b/examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function.sol @@ -0,0 +1,10 @@ +contract C { + function f() public pure returns(uint256) { return 1; } + function g() public pure returns(uint256) { return 2; } + function test(bool b) public returns(uint256) { + return (b ? C.f : C.g)(); + } +} +// ---- +// test(bool): true -> 1 +// test(bool): false -> 2 diff --git a/examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function_standard_input.json b/examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function_standard_input.json new file mode 100644 index 00000000..457c9ef0 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_ternary_contract_public_function/ternary_contract_public_function_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "mapping_of_functions.sol": { + "content": "contract Flow {\n bool public success;\n\n mapping(address => function() internal) stages;\n\n function stage0() internal {\n stages[msg.sender] = stage1;\n }\n\n function stage1() internal {\n stages[msg.sender] = stage2;\n }\n\n function stage2() internal {\n success = true;\n }\n\n constructor() {\n stages[msg.sender] = stage0;\n }\n\n function f() public returns (uint256) {\n stages[msg.sender]();\n return 7;\n }\n}\n// ----\n// success() -> false\n// f() -> 7\n// f() -> 7\n// success() -> false\n// f() -> 7\n// success() -> true\n" + }, + "function_delete_storage.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function() returns (uint256) internal y;\n\n function set() public returns (uint256) {\n y = a;\n return y();\n }\n\n function d() public returns (uint256) {\n delete y;\n return 1;\n }\n\n function ca() public returns (uint256) {\n return y();\n }\n}\n// ----\n// set() -> 7\n// ca() -> 7\n// d() -> 1\n// ca() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_ternary.sol": { + "content": "contract C {\n\tfunction f() public {}\n\tfunction g() public {}\n\tfunction h(bool c) public returns (bytes4) {\n\t\treturn (c ? this.f : this.g).selector;\n\t}\n}\n// ----\n// h(bool): true -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// h(bool): false -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "selector_2.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract D {\n function test() public returns (bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "function_delete_stack.sol": { + "content": "contract C {\n function a() public returns (uint256) {\n return 7;\n }\n\n function test() public returns (uint256) {\n function() returns (uint256) y = a;\n delete y;\n y();\n }\n}\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "selector_1.sol": { + "content": "contract B {\n function ext() external {}\n function pub() public {}\n}\n\ncontract C is B {\n function test() public returns (bytes4, bytes4, bytes4, bytes4) {\n return (B.ext.selector, B.pub.selector, this.ext.selector, pub.selector);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// test() -> 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000, 0xcf9f23b500000000000000000000000000000000000000000000000000000000, 0x7defb41000000000000000000000000000000000000000000000000000000000\n" + }, + "comparison_operator_for_external_function_cleans_dirty_bits.sol": { + "content": "contract C {\n function g() external {}\n function comparison_operators_for_external_function_pointers_with_dirty_bits() external returns (bool) {\n function() external g_ptr_dirty = this.g;\n assembly {\n g_ptr_dirty.address := or(g_ptr_dirty.address, shl(160, sub(0,1)))\n g_ptr_dirty.selector := or(g_ptr_dirty.selector, shl(32, sub(0,1)))\n }\n function() external g_ptr = this.g;\n return g_ptr == g_ptr_dirty;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// comparison_operators_for_external_function_pointers_with_dirty_bits() -> true\n" + }, + "address_member.sol": { + "content": "contract C {\n function f() public view returns (address a1, address a2) {\n a1 = this.f.address;\n this.f.address;\n [this.f.address][0];\n a2 = [this.f.address][0];\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e, 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "ternary_contract_internal_function.sol": { + "content": "contract C {\n function f() internal pure returns(uint256) { return 1;}\n function g() internal pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + }, + "duplicated_function_definition_with_same_id_in_internal_dispatcher.sol": { + "content": "contract C {\n function a() internal {}\n function f() public {\n function() ptr1 = a;\n function() ptr2 = a;\n }\n}\n// ----\n// f()\n" + }, + "function_external_delete_storage.sol": { + "content": "contract C {\n function() external public x;\n uint public y = 0;\n\n function increment() public {\n ++y;\n }\n\n function set() external {\n x = this.increment;\n }\n\n function incrementIndirectly() public {\n x();\n }\n\n function deleteFunction() public {\n // used to lead to an ICE during IR\n delete x;\n }\n}\n// ----\n// x() -> 0\n// y() -> 0\n// increment() ->\n// y() -> 1\n// set() ->\n// x() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79ed09de08a0000000000000000\n// increment() ->\n// y() -> 2\n// incrementIndirectly() ->\n// y() -> 3\n// deleteFunction() ->\n// increment() ->\n// y() -> 4\n// incrementIndirectly() -> FAILURE\n// y() -> 4\n" + }, + "pass_function_types_internally.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256) {\n return eval(g, x);\n }\n\n function eval(function(uint) internal returns (uint) x, uint a) internal returns (uint) {\n return x(a);\n }\n\n function g(uint256 x) public pure returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f(uint256): 7 -> 8\n" + }, + "ternary_contract_public_function.sol": { + "content": "contract C {\n function f() public pure returns(uint256) { return 1; }\n function g() public pure returns(uint256) { return 2; }\n function test(bool b) public returns(uint256) {\n return (b ? C.f : C.g)();\n }\n}\n// ----\n// test(bool): true -> 1\n// test(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call.sol b/examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call.sol new file mode 100644 index 00000000..b55de087 --- /dev/null +++ b/examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call.sol @@ -0,0 +1,10 @@ +contract Test { + function() internal x; + + function f() public returns (uint256 r) { + x(); + return 2; + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call_standard_input.json b/examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call_standard_input.json new file mode 100644 index 00000000..d88b81fd --- /dev/null +++ b/examples/test/semanticTests/functionTypes_uninitialized_internal_storage_function_call/uninitialized_internal_storage_function_call_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "selector_assignment_expression.sol": { + "content": "contract C {\n bool public z;\n function f() public {\n ((z = true) ? this.f : this.f).selector;\n }\n}\n\n// ----\n// f()\n// z() -> true\n" + }, + "comparison_operators_for_external_functions.sol": { + "content": "contract C {\n function f() external {}\n function g() external {}\n function h() pure external {}\n function i() view external {}\n\n function comparison_operators_for_external_functions() public returns (bool) {\n assert(\n this.f != this.g &&\n this.f != this.h &&\n this.f != this.i &&\n\n this.g != this.h &&\n this.g != this.i &&\n\n this.h != this.i &&\n\n this.f == this.f &&\n this.g == this.g &&\n this.h == this.h &&\n this.i == this.i\n );\n return true;\n }\n\n function comparison_operators_for_local_external_function_pointers() public returns (bool) {\n function () external f_local = this.f;\n function () external g_local = this.g;\n function () external pure h_local = this.h;\n function () external view i_local = this.i;\n\n assert(\n f_local == this.f &&\n g_local == this.g &&\n h_local == this.h &&\n i_local == this.i &&\n\n f_local != this.g &&\n f_local != this.h &&\n f_local != this.i &&\n\n g_local != this.f &&\n g_local != this.h &&\n g_local != this.i &&\n\n h_local != this.f &&\n h_local != this.g &&\n h_local != this.i &&\n\n i_local != this.f &&\n i_local != this.g &&\n i_local != this.h\n );\n\n assert(\n f_local == f_local &&\n f_local != g_local &&\n f_local != h_local &&\n f_local != i_local\n );\n\n assert(\n g_local == g_local &&\n g_local != h_local &&\n g_local != i_local\n );\n\n assert(\n h_local == h_local &&\n i_local == i_local &&\n h_local != i_local\n );\n\n return true;\n }\n}\n// ----\n// comparison_operators_for_external_functions() -> true\n// comparison_operators_for_local_external_function_pointers() -> true\n" + }, + "stack_height_check_on_adding_gas_variable_to_function.sol": { + "content": "contract C {\n function g() external {}\n function h() external payable {}\n function test_function() external returns (bool){\n assert (\n this.g.address == this.g.address &&\n this.g{gas: 42}.address == this.g.address &&\n this.g{gas: 42}.selector == this.g.selector\n );\n assert (\n this.h.address == this.h.address &&\n this.h{gas: 42}.address == this.h.address &&\n this.h{gas: 42}.selector == this.h.selector\n );\n assert (\n this.h{gas: 42, value: 5}.address == this.h.address &&\n this.h{gas: 42, value: 5}.selector == this.h.selector\n );\n return true;\n }\n}\n// ----\n// test_function() -> true\n" + }, + "function_type_library_internal.sol": { + "content": "library Utils {\n function reduce(\n uint256[] memory array,\n function(uint, uint) internal returns (uint) f,\n uint256 init\n ) internal returns (uint256) {\n for (uint256 i = 0; i < array.length; i++) {\n init = f(array[i], init);\n }\n return init;\n }\n\n function sum(uint256 a, uint256 b) internal returns (uint256) {\n return a + b;\n }\n}\n\n\ncontract C {\n function f(uint256[] memory x) public returns (uint256) {\n return Utils.reduce(x, Utils.sum, 0);\n }\n}\n// ----\n// f(uint256[]): 0x20, 0x3, 0x1, 0x7, 0x3 -> 11\n" + }, + "struct_with_functions.sol": { + "content": "struct S {\n uint16 a;\n function() returns (uint) x;\n uint16 b;\n}\ncontract Flow {\n S[2] t;\n\n function X() internal pure returns (uint) {\n return 1;\n }\n\n function Y() internal pure returns (uint) {\n return 2;\n }\n\n constructor() {\n t[0].a = 0xff07;\n t[0].b = 0xff07;\n t[1].x = Y;\n t[1].a = 0xff07;\n t[1].b = 0xff07;\n t[0].x = X;\n }\n\n function f() public returns (uint, uint) {\n return (t[0].x(), t[1].x());\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "inline_array_with_value_call_option.sol": { + "content": "contract C {\n function f() external payable returns (uint) { assert(msg.value > 0); return 1; }\n function g() external payable returns (uint) { assert(msg.value > 0); return 2; }\n\n function h() public payable returns (uint) {\n return [this.f, this.g][0]{value: 1}();\n }\n}\n// ----\n// h(), 1 ether -> 1\n" + }, + "uninitialized_internal_storage_function_call.sol": { + "content": "contract Test {\n function() internal x;\n\n function f() public returns (uint256 r) {\n x();\n return 2;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct.sol b/examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct.sol new file mode 100644 index 00000000..d824897e --- /dev/null +++ b/examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct.sol @@ -0,0 +1,29 @@ +contract C { + struct Y { + uint a; + uint b; + } + mapping(uint256 => Y)[] public m; + mapping(uint256 => Y)[3] public n; + constructor() { + m.push(); + m.push(); + m[1][0].a = 1; + m[1][0].b = 2; + m[1][1].a = 3; + m[1][1].b = 4; + n[1][0].a = 7; + n[1][0].b = 8; + n[1][1].a = 9; + n[1][1].b = 10; + } +} +// ---- +// m(uint256,uint256): 0, 0 -> 0x00, 0x00 +// m(uint256,uint256): 1, 0 -> 1, 2 +// m(uint256,uint256): 1, 1 -> 3, 4 +// m(uint256,uint256): 1, 2 -> 0x00, 0x00 +// n(uint256,uint256): 0, 0 -> 0x00, 0x00 +// n(uint256,uint256): 1, 0 -> 7, 8 +// n(uint256,uint256): 1, 1 -> 9, 0x0a +// n(uint256,uint256): 1, 2 -> 0x00, 0x00 diff --git a/examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct_standard_input.json b/examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct_standard_input.json new file mode 100644 index 00000000..380896be --- /dev/null +++ b/examples/test/semanticTests/getters_array_mapping_struct/array_mapping_struct_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_arrays/arrays.sol b/examples/test/semanticTests/getters_arrays/arrays.sol new file mode 100644 index 00000000..0ce2cdfc --- /dev/null +++ b/examples/test/semanticTests/getters_arrays/arrays.sol @@ -0,0 +1,12 @@ +contract C { + uint8[][2] public a; + constructor() { + a[1].push(3); + a[1].push(4); + } +} +// ---- +// a(uint256,uint256): 0, 0 -> FAILURE +// a(uint256,uint256): 1, 0 -> 3 +// a(uint256,uint256): 1, 1 -> 4 +// a(uint256,uint256): 2, 0 -> FAILURE diff --git a/examples/test/semanticTests/getters_arrays/arrays_standard_input.json b/examples/test/semanticTests/getters_arrays/arrays_standard_input.json new file mode 100644 index 00000000..d6c9025e --- /dev/null +++ b/examples/test/semanticTests/getters_arrays/arrays_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_bytes/bytes.sol b/examples/test/semanticTests/getters_bytes/bytes.sol new file mode 100644 index 00000000..c22403c7 --- /dev/null +++ b/examples/test/semanticTests/getters_bytes/bytes.sol @@ -0,0 +1,8 @@ +contract C { + bytes public b; + constructor() { + b = "abc"; + } +} +// ---- +// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/getters_bytes/bytes_standard_input.json b/examples/test/semanticTests/getters_bytes/bytes_standard_input.json new file mode 100644 index 00000000..d5010ea7 --- /dev/null +++ b/examples/test/semanticTests/getters_bytes/bytes_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_mapping/mapping.sol b/examples/test/semanticTests/getters_mapping/mapping.sol new file mode 100644 index 00000000..524cac36 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping/mapping.sol @@ -0,0 +1,9 @@ +contract C { + mapping(uint => mapping(uint => uint)) public x; + constructor() { + x[1][2] = 3; + } +} +// ---- +// x(uint256,uint256): 1, 2 -> 3 +// x(uint256,uint256): 0, 0 -> 0 diff --git a/examples/test/semanticTests/getters_mapping/mapping_standard_input.json b/examples/test/semanticTests/getters_mapping/mapping_standard_input.json new file mode 100644 index 00000000..6475c232 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping/mapping_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct.sol b/examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct.sol new file mode 100644 index 00000000..60683dfc --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct.sol @@ -0,0 +1,27 @@ +contract C { + struct Y { + uint a; + uint b; + } + mapping(uint256 => Y[]) public m; + mapping(uint256 => Y[3]) public n; + constructor() { + m[1].push().a = 1; + m[1][0].b = 2; + m[1].push().a = 3; + m[1][1].b = 4; + n[1][0].a = 7; + n[1][0].b = 8; + n[1][1].a = 9; + n[1][1].b = 10; + } +} +// ---- +// m(uint256,uint256): 0, 0 -> FAILURE +// m(uint256,uint256): 1, 0 -> 1, 2 +// m(uint256,uint256): 1, 1 -> 3, 4 +// m(uint256,uint256): 1, 2 -> FAILURE +// n(uint256,uint256): 0, 0 -> 0x00, 0x00 +// n(uint256,uint256): 1, 0 -> 7, 8 +// n(uint256,uint256): 1, 1 -> 9, 0x0a +// n(uint256,uint256): 1, 2 -> 0x00, 0x00 diff --git a/examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct_standard_input.json b/examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct_standard_input.json new file mode 100644 index 00000000..30897eac --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_array_struct/mapping_array_struct_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_mapping_of_string/mapping_of_string.sol b/examples/test/semanticTests/getters_mapping_of_string/mapping_of_string.sol new file mode 100644 index 00000000..db8de806 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_of_string/mapping_of_string.sol @@ -0,0 +1,16 @@ +contract C { + mapping(string => uint8[3]) public x; + constructor() { + x["abc"][0] = 1; + x["abc"][2] = 3; + x["abc"][1] = 2; + x["def"][1] = 9; + } +} +// ---- +// x(string,uint256): 0x40, 0, 3, "abc" -> 1 +// x(string,uint256): 0x40, 1, 3, "abc" -> 2 +// x(string,uint256): 0x40, 2, 3, "abc" -> 3 +// x(string,uint256): 0x40, 0, 3, "def" -> 0x00 +// x(string,uint256): 0x40, 1, 3, "def" -> 9 +// x(string,uint256): 0x40, 2, 3, "def" -> 0x00 diff --git a/examples/test/semanticTests/getters_mapping_of_string/mapping_of_string_standard_input.json b/examples/test/semanticTests/getters_mapping_of_string/mapping_of_string_standard_input.json new file mode 100644 index 00000000..89fa877c --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_of_string/mapping_of_string_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_with_names.sol": { + "content": "contract C {\n mapping(uint a => mapping(uint b => uint c)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "string_and_bytes.sol": { + "content": "contract C {\n string public a;\n string public b;\n bytes public c;\n string public d = \"abcd\";\n constructor() {\n a = \"hello world\";\n b = hex\"41424344\";\n c = hex\"ff077fff\";\n }\n}\n// ----\n// a() -> 0x20, 11, \"hello world\"\n// b() -> 0x20, 4, \"ABCD\"\n// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552\n// d() -> 0x20, 4, \"abcd\"\n" + }, + "struct_with_bytes_simple.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n }\n}\n// ----\n// s() -> 0x07, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "value_types.sol": { + "content": "contract C {\n uint8 public a;\n uint16 public b;\n uint128 public c;\n uint public d;\n bytes1 public e;\n bytes20 public f;\n bytes32 public g;\n bool public h;\n address public i;\n constructor() {\n a = 3;\n b = 4;\n c = 5;\n d = 6;\n e = bytes1(uint8(0x7f));\n f = bytes20(uint160(0x6465616462656566313564656164000000000010));\n g = bytes32(uint256(0x6465616462656566313564656164000000000000000000000000000000000010));\n h = true;\n i = address(type(uint160).max / 3);\n }\n}\n// ----\n// a() -> 3\n// b() -> 4\n// c() -> 5\n// d() -> 6\n// e() -> 0x7f00000000000000000000000000000000000000000000000000000000000000\n// f() -> 0x6465616462656566313564656164000000000010000000000000000000000000\n// g() -> 0x6465616462656566313564656164000000000000000000000000000000000010\n// h() -> true\n// i() -> 0x5555555555555555555555555555555555555555\n" + }, + "mapping_of_string.sol": { + "content": "contract C {\n mapping(string => uint8[3]) public x;\n constructor() {\n x[\"abc\"][0] = 1;\n x[\"abc\"][2] = 3;\n x[\"abc\"][1] = 2;\n x[\"def\"][1] = 9;\n }\n}\n// ----\n// x(string,uint256): 0x40, 0, 3, \"abc\" -> 1\n// x(string,uint256): 0x40, 1, 3, \"abc\" -> 2\n// x(string,uint256): 0x40, 2, 3, \"abc\" -> 3\n// x(string,uint256): 0x40, 0, 3, \"def\" -> 0x00\n// x(string,uint256): 0x40, 1, 3, \"def\" -> 9\n// x(string,uint256): 0x40, 2, 3, \"def\" -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct.sol b/examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct.sol new file mode 100644 index 00000000..d601fd90 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct.sol @@ -0,0 +1,18 @@ +contract C { + struct S { + uint8 a; + uint16 b; + uint128 c; + uint d; + } + mapping(uint => mapping(uint => S)) public x; + constructor() { + x[1][2].a = 3; + x[1][2].b = 4; + x[1][2].c = 5; + x[1][2].d = 6; + } +} +// ---- +// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6 +// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00 diff --git a/examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct_standard_input.json b/examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct_standard_input.json new file mode 100644 index 00000000..8c423176 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_to_struct/mapping_to_struct_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_mapping_with_names/mapping_with_names.sol b/examples/test/semanticTests/getters_mapping_with_names/mapping_with_names.sol new file mode 100644 index 00000000..290a8880 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_with_names/mapping_with_names.sol @@ -0,0 +1,9 @@ +contract C { + mapping(uint a => mapping(uint b => uint c)) public x; + constructor() { + x[1][2] = 3; + } +} +// ---- +// x(uint256,uint256): 1, 2 -> 3 +// x(uint256,uint256): 0, 0 -> 0 diff --git a/examples/test/semanticTests/getters_mapping_with_names/mapping_with_names_standard_input.json b/examples/test/semanticTests/getters_mapping_with_names/mapping_with_names_standard_input.json new file mode 100644 index 00000000..9db7feb8 --- /dev/null +++ b/examples/test/semanticTests/getters_mapping_with_names/mapping_with_names_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_with_names.sol": { + "content": "contract C {\n mapping(uint a => mapping(uint b => uint c)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_string_and_bytes/string_and_bytes.sol b/examples/test/semanticTests/getters_string_and_bytes/string_and_bytes.sol new file mode 100644 index 00000000..f9cf7316 --- /dev/null +++ b/examples/test/semanticTests/getters_string_and_bytes/string_and_bytes.sol @@ -0,0 +1,16 @@ +contract C { + string public a; + string public b; + bytes public c; + string public d = "abcd"; + constructor() { + a = "hello world"; + b = hex"41424344"; + c = hex"ff077fff"; + } +} +// ---- +// a() -> 0x20, 11, "hello world" +// b() -> 0x20, 4, "ABCD" +// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552 +// d() -> 0x20, 4, "abcd" diff --git a/examples/test/semanticTests/getters_string_and_bytes/string_and_bytes_standard_input.json b/examples/test/semanticTests/getters_string_and_bytes/string_and_bytes_standard_input.json new file mode 100644 index 00000000..671b5da6 --- /dev/null +++ b/examples/test/semanticTests/getters_string_and_bytes/string_and_bytes_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_with_names.sol": { + "content": "contract C {\n mapping(uint a => mapping(uint b => uint c)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "string_and_bytes.sol": { + "content": "contract C {\n string public a;\n string public b;\n bytes public c;\n string public d = \"abcd\";\n constructor() {\n a = \"hello world\";\n b = hex\"41424344\";\n c = hex\"ff077fff\";\n }\n}\n// ----\n// a() -> 0x20, 11, \"hello world\"\n// b() -> 0x20, 4, \"ABCD\"\n// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552\n// d() -> 0x20, 4, \"abcd\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes.sol b/examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes.sol new file mode 100644 index 00000000..477a1297 --- /dev/null +++ b/examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes.sol @@ -0,0 +1,18 @@ +contract C { + struct S { + uint a; + bytes b; + mapping(uint => uint) c; + uint[] d; + } + uint shifter; + S public s; + constructor() { + s.a = 7; + s.b = "abc"; + s.c[0] = 9; + s.d.push(10); + } +} +// ---- +// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes_standard_input.json b/examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes_standard_input.json new file mode 100644 index 00000000..acdb871f --- /dev/null +++ b/examples/test/semanticTests/getters_struct_with_bytes/struct_with_bytes_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple.sol b/examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple.sol new file mode 100644 index 00000000..281b29c8 --- /dev/null +++ b/examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple.sol @@ -0,0 +1,17 @@ +contract C { + struct S { + uint a; + bytes b; + mapping(uint => uint) c; + uint[] d; + } + uint shifter; + S public s; + constructor() { + s.a = 7; + s.b = "abc"; + s.c[0] = 9; + } +} +// ---- +// s() -> 0x07, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple_standard_input.json b/examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple_standard_input.json new file mode 100644 index 00000000..79cf9c6f --- /dev/null +++ b/examples/test/semanticTests/getters_struct_with_bytes_simple/struct_with_bytes_simple_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_with_names.sol": { + "content": "contract C {\n mapping(uint a => mapping(uint b => uint c)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "string_and_bytes.sol": { + "content": "contract C {\n string public a;\n string public b;\n bytes public c;\n string public d = \"abcd\";\n constructor() {\n a = \"hello world\";\n b = hex\"41424344\";\n c = hex\"ff077fff\";\n }\n}\n// ----\n// a() -> 0x20, 11, \"hello world\"\n// b() -> 0x20, 4, \"ABCD\"\n// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552\n// d() -> 0x20, 4, \"abcd\"\n" + }, + "struct_with_bytes_simple.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n }\n}\n// ----\n// s() -> 0x07, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_transient_value_types/transient_value_types.sol b/examples/test/semanticTests/getters_transient_value_types/transient_value_types.sol new file mode 100644 index 00000000..852e96ba --- /dev/null +++ b/examples/test/semanticTests/getters_transient_value_types/transient_value_types.sol @@ -0,0 +1,14 @@ +contract C { + int8 public transient x; + + function f() public returns(int8) { + x = -1; + return this.x(); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// x() -> 0 +// f() -> -1 +// x() -> 0 diff --git a/examples/test/semanticTests/getters_transient_value_types/transient_value_types_standard_input.json b/examples/test/semanticTests/getters_transient_value_types/transient_value_types_standard_input.json new file mode 100644 index 00000000..14775590 --- /dev/null +++ b/examples/test/semanticTests/getters_transient_value_types/transient_value_types_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call.sol b/examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call.sol new file mode 100644 index 00000000..912fca4f --- /dev/null +++ b/examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call.sol @@ -0,0 +1,22 @@ +contract C { + int8 public transient x; + + function f() public returns(int8) { + x = -1; + return this.h(); + } + function g() public { + x = x - 1; + } + function h() public returns(int8) { + this.g(); + return this.x(); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// x() -> 0 +// f() -> -2 +// h() -> -1 +// x() -> 0 diff --git a/examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call_standard_input.json b/examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call_standard_input.json new file mode 100644 index 00000000..2c0e8908 --- /dev/null +++ b/examples/test/semanticTests/getters_transient_value_types_multi_frame_call/transient_value_types_multi_frame_call_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_with_names.sol": { + "content": "contract C {\n mapping(uint a => mapping(uint b => uint c)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "string_and_bytes.sol": { + "content": "contract C {\n string public a;\n string public b;\n bytes public c;\n string public d = \"abcd\";\n constructor() {\n a = \"hello world\";\n b = hex\"41424344\";\n c = hex\"ff077fff\";\n }\n}\n// ----\n// a() -> 0x20, 11, \"hello world\"\n// b() -> 0x20, 4, \"ABCD\"\n// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552\n// d() -> 0x20, 4, \"abcd\"\n" + }, + "struct_with_bytes_simple.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n }\n}\n// ----\n// s() -> 0x07, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "value_types.sol": { + "content": "contract C {\n uint8 public a;\n uint16 public b;\n uint128 public c;\n uint public d;\n bytes1 public e;\n bytes20 public f;\n bytes32 public g;\n bool public h;\n address public i;\n constructor() {\n a = 3;\n b = 4;\n c = 5;\n d = 6;\n e = bytes1(uint8(0x7f));\n f = bytes20(uint160(0x6465616462656566313564656164000000000010));\n g = bytes32(uint256(0x6465616462656566313564656164000000000000000000000000000000000010));\n h = true;\n i = address(type(uint160).max / 3);\n }\n}\n// ----\n// a() -> 3\n// b() -> 4\n// c() -> 5\n// d() -> 6\n// e() -> 0x7f00000000000000000000000000000000000000000000000000000000000000\n// f() -> 0x6465616462656566313564656164000000000010000000000000000000000000\n// g() -> 0x6465616462656566313564656164000000000000000000000000000000000010\n// h() -> true\n// i() -> 0x5555555555555555555555555555555555555555\n" + }, + "mapping_of_string.sol": { + "content": "contract C {\n mapping(string => uint8[3]) public x;\n constructor() {\n x[\"abc\"][0] = 1;\n x[\"abc\"][2] = 3;\n x[\"abc\"][1] = 2;\n x[\"def\"][1] = 9;\n }\n}\n// ----\n// x(string,uint256): 0x40, 0, 3, \"abc\" -> 1\n// x(string,uint256): 0x40, 1, 3, \"abc\" -> 2\n// x(string,uint256): 0x40, 2, 3, \"abc\" -> 3\n// x(string,uint256): 0x40, 0, 3, \"def\" -> 0x00\n// x(string,uint256): 0x40, 1, 3, \"def\" -> 9\n// x(string,uint256): 0x40, 2, 3, \"def\" -> 0x00\n" + }, + "transient_value_types_multi_frame_call.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.h();\n }\n function g() public {\n x = x - 1;\n }\n function h() public returns(int8) {\n this.g();\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -2\n// h() -> -1\n// x() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/getters_value_types/value_types.sol b/examples/test/semanticTests/getters_value_types/value_types.sol new file mode 100644 index 00000000..a8a8759e --- /dev/null +++ b/examples/test/semanticTests/getters_value_types/value_types.sol @@ -0,0 +1,32 @@ +contract C { + uint8 public a; + uint16 public b; + uint128 public c; + uint public d; + bytes1 public e; + bytes20 public f; + bytes32 public g; + bool public h; + address public i; + constructor() { + a = 3; + b = 4; + c = 5; + d = 6; + e = bytes1(uint8(0x7f)); + f = bytes20(uint160(0x6465616462656566313564656164000000000010)); + g = bytes32(uint256(0x6465616462656566313564656164000000000000000000000000000000000010)); + h = true; + i = address(type(uint160).max / 3); + } +} +// ---- +// a() -> 3 +// b() -> 4 +// c() -> 5 +// d() -> 6 +// e() -> 0x7f00000000000000000000000000000000000000000000000000000000000000 +// f() -> 0x6465616462656566313564656164000000000010000000000000000000000000 +// g() -> 0x6465616462656566313564656164000000000000000000000000000000000010 +// h() -> true +// i() -> 0x5555555555555555555555555555555555555555 diff --git a/examples/test/semanticTests/getters_value_types/value_types_standard_input.json b/examples/test/semanticTests/getters_value_types/value_types_standard_input.json new file mode 100644 index 00000000..c92d2304 --- /dev/null +++ b/examples/test/semanticTests/getters_value_types/value_types_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "array_mapping_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y)[] public m;\n mapping(uint256 => Y)[3] public n;\n constructor() {\n m.push();\n m.push();\n m[1][0].a = 1;\n m[1][0].b = 2;\n m[1][1].a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> 0x00, 0x00\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> 0x00, 0x00\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "transient_value_types.sol": { + "content": "contract C {\n int8 public transient x;\n\n function f() public returns(int8) {\n x = -1;\n return this.x();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// f() -> -1\n// x() -> 0\n" + }, + "mapping_array_struct.sol": { + "content": "contract C {\n struct Y {\n uint a;\n uint b;\n }\n mapping(uint256 => Y[]) public m;\n mapping(uint256 => Y[3]) public n;\n constructor() {\n m[1].push().a = 1;\n m[1][0].b = 2;\n m[1].push().a = 3;\n m[1][1].b = 4;\n n[1][0].a = 7;\n n[1][0].b = 8;\n n[1][1].a = 9;\n n[1][1].b = 10;\n }\n}\n// ----\n// m(uint256,uint256): 0, 0 -> FAILURE\n// m(uint256,uint256): 1, 0 -> 1, 2\n// m(uint256,uint256): 1, 1 -> 3, 4\n// m(uint256,uint256): 1, 2 -> FAILURE\n// n(uint256,uint256): 0, 0 -> 0x00, 0x00\n// n(uint256,uint256): 1, 0 -> 7, 8\n// n(uint256,uint256): 1, 1 -> 9, 0x0a\n// n(uint256,uint256): 1, 2 -> 0x00, 0x00\n" + }, + "arrays.sol": { + "content": "contract C {\n uint8[][2] public a;\n constructor() {\n a[1].push(3);\n a[1].push(4);\n }\n}\n// ----\n// a(uint256,uint256): 0, 0 -> FAILURE\n// a(uint256,uint256): 1, 0 -> 3\n// a(uint256,uint256): 1, 1 -> 4\n// a(uint256,uint256): 2, 0 -> FAILURE\n" + }, + "mapping_to_struct.sol": { + "content": "contract C {\n struct S {\n uint8 a;\n uint16 b;\n uint128 c;\n uint d;\n }\n mapping(uint => mapping(uint => S)) public x;\n constructor() {\n x[1][2].a = 3;\n x[1][2].b = 4;\n x[1][2].c = 5;\n x[1][2].d = 6;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3, 4, 5, 6\n// x(uint256,uint256): 0, 0 -> 0x00, 0x00, 0x00, 0x00\n" + }, + "mapping.sol": { + "content": "contract C {\n mapping(uint => mapping(uint => uint)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "bytes.sol": { + "content": "contract C {\n bytes public b;\n constructor() {\n b = \"abc\";\n }\n}\n// ----\n// b() -> 0x20, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "struct_with_bytes.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n s.d.push(10);\n }\n}\n// ----\n// s() -> 7, 0x40, 3, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_with_names.sol": { + "content": "contract C {\n mapping(uint a => mapping(uint b => uint c)) public x;\n constructor() {\n x[1][2] = 3;\n }\n}\n// ----\n// x(uint256,uint256): 1, 2 -> 3\n// x(uint256,uint256): 0, 0 -> 0\n" + }, + "string_and_bytes.sol": { + "content": "contract C {\n string public a;\n string public b;\n bytes public c;\n string public d = \"abcd\";\n constructor() {\n a = \"hello world\";\n b = hex\"41424344\";\n c = hex\"ff077fff\";\n }\n}\n// ----\n// a() -> 0x20, 11, \"hello world\"\n// b() -> 0x20, 4, \"ABCD\"\n// c() -> 0x20, 4, -439061522557375173052089223601630338202760422010735733633791622124826263552\n// d() -> 0x20, 4, \"abcd\"\n" + }, + "struct_with_bytes_simple.sol": { + "content": "contract C {\n struct S {\n uint a;\n bytes b;\n mapping(uint => uint) c;\n uint[] d;\n }\n uint shifter;\n S public s;\n constructor() {\n s.a = 7;\n s.b = \"abc\";\n s.c[0] = 9;\n }\n}\n// ----\n// s() -> 0x07, 0x40, 0x03, 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "value_types.sol": { + "content": "contract C {\n uint8 public a;\n uint16 public b;\n uint128 public c;\n uint public d;\n bytes1 public e;\n bytes20 public f;\n bytes32 public g;\n bool public h;\n address public i;\n constructor() {\n a = 3;\n b = 4;\n c = 5;\n d = 6;\n e = bytes1(uint8(0x7f));\n f = bytes20(uint160(0x6465616462656566313564656164000000000010));\n g = bytes32(uint256(0x6465616462656566313564656164000000000000000000000000000000000010));\n h = true;\n i = address(type(uint160).max / 3);\n }\n}\n// ----\n// a() -> 3\n// b() -> 4\n// c() -> 5\n// d() -> 6\n// e() -> 0x7f00000000000000000000000000000000000000000000000000000000000000\n// f() -> 0x6465616462656566313564656164000000000010000000000000000000000000\n// g() -> 0x6465616462656566313564656164000000000000000000000000000000000010\n// h() -> true\n// i() -> 0x5555555555555555555555555555555555555555\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration.sol b/examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration.sol new file mode 100644 index 00000000..3f71a31e --- /dev/null +++ b/examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration.sol @@ -0,0 +1,8 @@ +contract A { + uint8 immutable a = 2; + function f() public view returns (uint) { + return a; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration_standard_input.json b/examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration_standard_input.json new file mode 100644 index 00000000..9841f1fd --- /dev/null +++ b/examples/test/semanticTests/immutable_assign_at_declaration/assign_at_declaration_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables.sol b/examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables.sol new file mode 100644 index 00000000..e1440be5 --- /dev/null +++ b/examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables.sol @@ -0,0 +1,18 @@ +contract C { + uint immutable public a; + uint immutable public b; + uint immutable public c; + uint immutable public d; + + constructor() { + a = 1; + b = a; + c = b; + d = c; + } +} +// ---- +// a() -> 1 +// b() -> 1 +// c() -> 1 +// d() -> 1 diff --git a/examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables_standard_input.json b/examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables_standard_input.json new file mode 100644 index 00000000..e0fd49b2 --- /dev/null +++ b/examples/test/semanticTests/immutable_assign_from_immutables/assign_from_immutables_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_delete/delete.sol b/examples/test/semanticTests/immutable_delete/delete.sol new file mode 100644 index 00000000..76e219a7 --- /dev/null +++ b/examples/test/semanticTests/immutable_delete/delete.sol @@ -0,0 +1,15 @@ +contract C { + uint8 immutable public a; + uint8 immutable public b = 0x42; + uint public c; + + constructor() { + delete a; + delete b; + c = b * 2 + a; + } +} +// ---- +// a() -> 0 +// b() -> 0 +// c() -> 0 diff --git a/examples/test/semanticTests/immutable_delete/delete_standard_input.json b/examples/test/semanticTests/immutable_delete/delete_standard_input.json new file mode 100644 index 00000000..82fe9fba --- /dev/null +++ b/examples/test/semanticTests/immutable_delete/delete_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor.sol b/examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor.sol new file mode 100644 index 00000000..0aafbae3 --- /dev/null +++ b/examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor.sol @@ -0,0 +1,20 @@ +contract A { + uint8 immutable a; + uint8 x; + + constructor() { + a = 3; + x = readA(); + } + + function readX() public view returns (uint8) { + return x; + } + + function readA() public view returns (uint8) { + return a; + } +} +// ---- +// readX() -> 3 +// readA() -> 3 diff --git a/examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor_standard_input.json b/examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor_standard_input.json new file mode 100644 index 00000000..4ccde47d --- /dev/null +++ b/examples/test/semanticTests/immutable_fun_read_in_ctor/fun_read_in_ctor_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + }, + "multiple_initializations.sol": { + "content": "contract A {\n uint immutable x = x + 1;\n uint immutable y = x += 2;\n\n constructor(uint) m(x += 16) m(x += 32) {\n x += 64;\n x += 128;\n }\n\n modifier m(uint) {\n _;\n }\n\n function get() public returns (uint) {\n return x;\n }\n}\n\ncontract B is A(A.x += 8) {\n constructor(uint) {}\n}\n\ncontract C is B {\n constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n" + }, + "internal_function_pointer.sol": { + "content": "contract C {\n\tfunction() internal view returns(uint256) immutable z;\n\tconstructor() {\n\t\tz = f;\n\t}\n\tfunction f() public view returns (uint256) {\n\t\treturn 7;\n\t}\n\tfunction callZ() public view returns (uint) {\n\t\treturn z();\n\t}\n}\n// ----\n// f() -> 7\n// callZ() -> 7\n" + }, + "immutable_signed.sol": { + "content": "contract C {\n int8 immutable a = -2;\n bytes2 immutable b = \"ab\";\n function() internal returns (uint) immutable f = g;\n function viaasm() view external returns (bytes32 x, bytes32 y) {\n int8 _a = a;\n bytes2 _b = b;\n assembly { x := _a y := _b }\n }\n function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "stub.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tconstructor() {\n\t\tx = 42;\n\t\ty = 23;\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// f() -> 84, 23\n" + }, + "uninitialized.sol": { + "content": "contract C {\n uint immutable u;\n bool immutable b;\n address immutable a;\n\n function get() public returns (uint, bool, address) {\n return (u, b, a);\n }\n}\n// ----\n// get() -> 0, false, 0x0\n" + }, + "fun_read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = readA();\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n\n\tfunction readA() public view returns (uint8) {\n\t\treturn a;\n\t}\n}\n// ----\n// readX() -> 3\n// readA() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_getter/getter.sol b/examples/test/semanticTests/immutable_getter/getter.sol new file mode 100644 index 00000000..bb4b191c --- /dev/null +++ b/examples/test/semanticTests/immutable_getter/getter.sol @@ -0,0 +1,5 @@ +contract C { + uint immutable public x = 1; +} +// ---- +// x() -> 1 diff --git a/examples/test/semanticTests/immutable_getter/getter_standard_input.json b/examples/test/semanticTests/immutable_getter/getter_standard_input.json new file mode 100644 index 00000000..8aaa629a --- /dev/null +++ b/examples/test/semanticTests/immutable_getter/getter_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor.sol b/examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor.sol new file mode 100644 index 00000000..2ef12c04 --- /dev/null +++ b/examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor.sol @@ -0,0 +1,17 @@ +contract A { + uint immutable public x = 1; + uint public y; + constructor() { + y = this.x(); + } +} +contract C { + function f() public returns (bool) { + try new A() { return false; } + catch { return true; } + } +} +// ==== +// EVMVersion: >=tangerineWhistle +// ---- +// f() -> true diff --git a/examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor_standard_input.json b/examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor_standard_input.json new file mode 100644 index 00000000..47b50f39 --- /dev/null +++ b/examples/test/semanticTests/immutable_getter_call_in_constructor/getter_call_in_constructor_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_immutable_signed/immutable_signed.sol b/examples/test/semanticTests/immutable_immutable_signed/immutable_signed.sol new file mode 100644 index 00000000..6bb193f8 --- /dev/null +++ b/examples/test/semanticTests/immutable_immutable_signed/immutable_signed.sol @@ -0,0 +1,13 @@ +contract C { + int8 immutable a = -2; + bytes2 immutable b = "ab"; + function() internal returns (uint) immutable f = g; + function viaasm() view external returns (bytes32 x, bytes32 y) { + int8 _a = a; + bytes2 _b = b; + assembly { x := _a y := _b } + } + function g() internal pure returns (uint) { return 2; } +} +// ---- +// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/immutable_immutable_signed/immutable_signed_standard_input.json b/examples/test/semanticTests/immutable_immutable_signed/immutable_signed_standard_input.json new file mode 100644 index 00000000..b67fce0e --- /dev/null +++ b/examples/test/semanticTests/immutable_immutable_signed/immutable_signed_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + }, + "multiple_initializations.sol": { + "content": "contract A {\n uint immutable x = x + 1;\n uint immutable y = x += 2;\n\n constructor(uint) m(x += 16) m(x += 32) {\n x += 64;\n x += 128;\n }\n\n modifier m(uint) {\n _;\n }\n\n function get() public returns (uint) {\n return x;\n }\n}\n\ncontract B is A(A.x += 8) {\n constructor(uint) {}\n}\n\ncontract C is B {\n constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n" + }, + "internal_function_pointer.sol": { + "content": "contract C {\n\tfunction() internal view returns(uint256) immutable z;\n\tconstructor() {\n\t\tz = f;\n\t}\n\tfunction f() public view returns (uint256) {\n\t\treturn 7;\n\t}\n\tfunction callZ() public view returns (uint) {\n\t\treturn z();\n\t}\n}\n// ----\n// f() -> 7\n// callZ() -> 7\n" + }, + "immutable_signed.sol": { + "content": "contract C {\n int8 immutable a = -2;\n bytes2 immutable b = \"ab\";\n function() internal returns (uint) immutable f = g;\n function viaasm() view external returns (bytes32 x, bytes32 y) {\n int8 _a = a;\n bytes2 _b = b;\n assembly { x := _a y := _b }\n }\n function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug.sol b/examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug.sol new file mode 100644 index 00000000..fed42462 --- /dev/null +++ b/examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug.sol @@ -0,0 +1,48 @@ +contract C { + int immutable x = 1; + int immutable y = 3; + + function f() public payable returns(int, int) { + uint a = uint(y / 1e8); + int256 b = x * y; + int24 c = int24(b * b >> 128); + int24 d = int24((100 * y + 1) >> 128); + int24 e = int24(x >> 128); + int256 f = x * 2; + if (c < 0) { + int256 g = (x * x * y) / x; + require((y >= 0 && g <= x) || (y < 0 && (x - y) > x)); + if (b >= f) { + require(x <= int256(uint256(type(uint168).max)) && x >= 0, ""); + b = (b * b) / f; + for (a = 0; a < a; a++) { + uint8 b; + assembly { + b := and(mload(a), 0xFF) + } + } + b += f; + } + require(d % e != 0); + c = -c; + } + return (x, ((x * (x - y)) / (x + y))); + } + + constructor () { + x--; + --x; + y++; + ++y; + --y; + } +} +// ==== +// compileViaYul: true +// ---- +// constructor() -> +// gas irOptimized: 73171 +// gas irOptimized code: 291200 +// gas legacy: 83499 +// gas legacy code: 408800 +// f() -> -1, 1 diff --git a/examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug_standard_input.json b/examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug_standard_input.json new file mode 100644 index 00000000..a24da877 --- /dev/null +++ b/examples/test/semanticTests/immutable_immutable_tag_too_large_bug/immutable_tag_too_large_bug_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_increment_decrement/increment_decrement.sol b/examples/test/semanticTests/immutable_increment_decrement/increment_decrement.sol new file mode 100644 index 00000000..14304513 --- /dev/null +++ b/examples/test/semanticTests/immutable_increment_decrement/increment_decrement.sol @@ -0,0 +1,18 @@ +contract C { + int immutable x = 1; + int immutable y = 3; + + constructor() { + x--; + --x; + y++; + ++y; + --y; + } + + function f() public view returns (int, int) { + return (x, y); + } +} +// ---- +// f() -> -1, 4 diff --git a/examples/test/semanticTests/immutable_increment_decrement/increment_decrement_standard_input.json b/examples/test/semanticTests/immutable_increment_decrement/increment_decrement_standard_input.json new file mode 100644 index 00000000..801997a7 --- /dev/null +++ b/examples/test/semanticTests/immutable_increment_decrement/increment_decrement_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_inheritance/inheritance.sol b/examples/test/semanticTests/immutable_inheritance/inheritance.sol new file mode 100644 index 00000000..889c273e --- /dev/null +++ b/examples/test/semanticTests/immutable_inheritance/inheritance.sol @@ -0,0 +1,30 @@ +contract A { + uint8 immutable a; + constructor() { + a = 4; + } +} +contract B is A { + uint8 immutable b; + constructor() { + b = 3; + } +} +contract C is A { + uint8 immutable c; + constructor() { + c = 2; + } +} +contract D is B, C { + uint8 immutable d; + + constructor() { + d = 1; + } + function f() public view returns (uint256, uint256, uint, uint) { + return (a, b, c, d); + } +} +// ---- +// f() -> 4, 3, 2, 1 diff --git a/examples/test/semanticTests/immutable_inheritance/inheritance_standard_input.json b/examples/test/semanticTests/immutable_inheritance/inheritance_standard_input.json new file mode 100644 index 00000000..2ccc5053 --- /dev/null +++ b/examples/test/semanticTests/immutable_inheritance/inheritance_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer.sol b/examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer.sol new file mode 100644 index 00000000..f56db7f2 --- /dev/null +++ b/examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer.sol @@ -0,0 +1,15 @@ +contract C { + function() internal view returns(uint256) immutable z; + constructor() { + z = f; + } + function f() public view returns (uint256) { + return 7; + } + function callZ() public view returns (uint) { + return z(); + } +} +// ---- +// f() -> 7 +// callZ() -> 7 diff --git a/examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer_standard_input.json b/examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer_standard_input.json new file mode 100644 index 00000000..04eb9dff --- /dev/null +++ b/examples/test/semanticTests/immutable_internal_function_pointer/internal_function_pointer_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + }, + "multiple_initializations.sol": { + "content": "contract A {\n uint immutable x = x + 1;\n uint immutable y = x += 2;\n\n constructor(uint) m(x += 16) m(x += 32) {\n x += 64;\n x += 128;\n }\n\n modifier m(uint) {\n _;\n }\n\n function get() public returns (uint) {\n return x;\n }\n}\n\ncontract B is A(A.x += 8) {\n constructor(uint) {}\n}\n\ncontract C is B {\n constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n" + }, + "internal_function_pointer.sol": { + "content": "contract C {\n\tfunction() internal view returns(uint256) immutable z;\n\tconstructor() {\n\t\tz = f;\n\t}\n\tfunction f() public view returns (uint256) {\n\t\treturn 7;\n\t}\n\tfunction callZ() public view returns (uint) {\n\t\treturn z();\n\t}\n}\n// ----\n// f() -> 7\n// callZ() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_multi_creation/multi_creation.sol b/examples/test/semanticTests/immutable_multi_creation/multi_creation.sol new file mode 100644 index 00000000..aa8a1ad8 --- /dev/null +++ b/examples/test/semanticTests/immutable_multi_creation/multi_creation.sol @@ -0,0 +1,37 @@ +contract A { + uint immutable a; + constructor() { + a = 7; + } + function f() public view returns (uint) { return a; } +} +contract B { + uint immutable a; + constructor() { + a = 5; + } + function f() public view returns (uint) { return a; } +} +contract C { + uint immutable a; + uint public x; + uint public y; + constructor() { + a = 3; + x = (new A()).f(); + y = (new B()).f(); + } + function f() public returns (uint256, uint, uint) { + return (a, (new A()).f(), (new B()).f()); + } +} +// ---- +// f() -> 3, 7, 5 +// gas irOptimized: 86796 +// gas irOptimized code: 37200 +// gas legacy: 87727 +// gas legacy code: 60800 +// gas legacyOptimized: 86770 +// gas legacyOptimized code: 37200 +// x() -> 7 +// y() -> 5 diff --git a/examples/test/semanticTests/immutable_multi_creation/multi_creation_standard_input.json b/examples/test/semanticTests/immutable_multi_creation/multi_creation_standard_input.json new file mode 100644 index 00000000..502ae2b6 --- /dev/null +++ b/examples/test/semanticTests/immutable_multi_creation/multi_creation_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations.sol b/examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations.sol new file mode 100644 index 00000000..b72f05b1 --- /dev/null +++ b/examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations.sol @@ -0,0 +1,27 @@ +contract A { + uint immutable x = x + 1; + uint immutable y = x += 2; + + constructor(uint) m(x += 16) m(x += 32) { + x += 64; + x += 128; + } + + modifier m(uint) { + _; + } + + function get() public returns (uint) { + return x; + } +} + +contract B is A(A.x += 8) { + constructor(uint) {} +} + +contract C is B { + constructor() B(x += 4) {} +} +// ---- +// get() -> 0xff diff --git a/examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations_standard_input.json b/examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations_standard_input.json new file mode 100644 index 00000000..e4f42d52 --- /dev/null +++ b/examples/test/semanticTests/immutable_multiple_initializations/multiple_initializations_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + }, + "multiple_initializations.sol": { + "content": "contract A {\n uint immutable x = x + 1;\n uint immutable y = x += 2;\n\n constructor(uint) m(x += 16) m(x += 32) {\n x += 64;\n x += 128;\n }\n\n modifier m(uint) {\n _;\n }\n\n function get() public returns (uint) {\n return x;\n }\n}\n\ncontract B is A(A.x += 8) {\n constructor(uint) {}\n}\n\ncontract C is B {\n constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor.sol b/examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor.sol new file mode 100644 index 00000000..329a3776 --- /dev/null +++ b/examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor.sol @@ -0,0 +1,15 @@ +contract A { + uint8 immutable a; + uint8 x; + + constructor() { + a = 3; + x = a; + } + + function readX() public view returns (uint8) { + return x; + } +} +// ---- +// readX() -> 3 diff --git a/examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor_standard_input.json b/examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor_standard_input.json new file mode 100644 index 00000000..a1be4c78 --- /dev/null +++ b/examples/test/semanticTests/immutable_read_in_ctor/read_in_ctor_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse.sol b/examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse.sol new file mode 100644 index 00000000..167bd48a --- /dev/null +++ b/examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse.sol @@ -0,0 +1,19 @@ +contract A { + uint16 public immutable a; + uint16 public immutable b; + uint16 public immutable c; + uint16[3] public x; + constructor() { + c = 0xffff; + b = 0x0f0f; + a = 0x1234; + x = [a, b, c]; + } +} +// ---- +// a() -> 4660 +// b() -> 0x0f0f +// c() -> 0xffff +// x(uint256): 0 -> 4660 +// x(uint256): 1 -> 0x0f0f +// x(uint256): 2 -> 0xffff diff --git a/examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse_standard_input.json b/examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse_standard_input.json new file mode 100644 index 00000000..f0f45b67 --- /dev/null +++ b/examples/test/semanticTests/immutable_small_types_in_reverse/small_types_in_reverse_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_stub/stub.sol b/examples/test/semanticTests/immutable_stub/stub.sol new file mode 100644 index 00000000..092edfab --- /dev/null +++ b/examples/test/semanticTests/immutable_stub/stub.sol @@ -0,0 +1,13 @@ +contract C { + uint256 immutable x; + uint256 immutable y; + constructor() { + x = 42; + y = 23; + } + function f() public view returns (uint256, uint256) { + return (x+x,y); + } +} +// ---- +// f() -> 84, 23 diff --git a/examples/test/semanticTests/immutable_stub/stub_standard_input.json b/examples/test/semanticTests/immutable_stub/stub_standard_input.json new file mode 100644 index 00000000..2fe86cb5 --- /dev/null +++ b/examples/test/semanticTests/immutable_stub/stub_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + }, + "multiple_initializations.sol": { + "content": "contract A {\n uint immutable x = x + 1;\n uint immutable y = x += 2;\n\n constructor(uint) m(x += 16) m(x += 32) {\n x += 64;\n x += 128;\n }\n\n modifier m(uint) {\n _;\n }\n\n function get() public returns (uint) {\n return x;\n }\n}\n\ncontract B is A(A.x += 8) {\n constructor(uint) {}\n}\n\ncontract C is B {\n constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n" + }, + "internal_function_pointer.sol": { + "content": "contract C {\n\tfunction() internal view returns(uint256) immutable z;\n\tconstructor() {\n\t\tz = f;\n\t}\n\tfunction f() public view returns (uint256) {\n\t\treturn 7;\n\t}\n\tfunction callZ() public view returns (uint) {\n\t\treturn z();\n\t}\n}\n// ----\n// f() -> 7\n// callZ() -> 7\n" + }, + "immutable_signed.sol": { + "content": "contract C {\n int8 immutable a = -2;\n bytes2 immutable b = \"ab\";\n function() internal returns (uint) immutable f = g;\n function viaasm() view external returns (bytes32 x, bytes32 y) {\n int8 _a = a;\n bytes2 _b = b;\n assembly { x := _a y := _b }\n }\n function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "stub.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tconstructor() {\n\t\tx = 42;\n\t\ty = 23;\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// f() -> 84, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_uninitialized/uninitialized.sol b/examples/test/semanticTests/immutable_uninitialized/uninitialized.sol new file mode 100644 index 00000000..f6d59ce7 --- /dev/null +++ b/examples/test/semanticTests/immutable_uninitialized/uninitialized.sol @@ -0,0 +1,11 @@ +contract C { + uint immutable u; + bool immutable b; + address immutable a; + + function get() public returns (uint, bool, address) { + return (u, b, a); + } +} +// ---- +// get() -> 0, false, 0x0 diff --git a/examples/test/semanticTests/immutable_uninitialized/uninitialized_standard_input.json b/examples/test/semanticTests/immutable_uninitialized/uninitialized_standard_input.json new file mode 100644 index 00000000..61f6a319 --- /dev/null +++ b/examples/test/semanticTests/immutable_uninitialized/uninitialized_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + }, + "delete.sol": { + "content": "contract C {\n uint8 immutable public a;\n uint8 immutable public b = 0x42;\n uint public c;\n\n constructor() {\n delete a;\n delete b;\n c = b * 2 + a;\n }\n}\n// ----\n// a() -> 0\n// b() -> 0\n// c() -> 0\n" + }, + "immutable_tag_too_large_bug.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n function f() public payable returns(int, int) {\n uint a = uint(y / 1e8);\n int256 b = x * y;\n int24 c = int24(b * b >> 128);\n int24 d = int24((100 * y + 1) >> 128);\n int24 e = int24(x >> 128);\n int256 f = x * 2;\n if (c < 0) {\n int256 g = (x * x * y) / x;\n require((y >= 0 && g <= x) || (y < 0 && (x - y) > x));\n if (b >= f) {\n require(x <= int256(uint256(type(uint168).max)) && x >= 0, \"\");\n b = (b * b) / f;\n for (a = 0; a < a; a++) {\n uint8 b;\n assembly {\n b := and(mload(a), 0xFF)\n }\n }\n b += f;\n }\n require(d % e != 0);\n c = -c;\n }\n return (x, ((x * (x - y)) / (x + y)));\n }\n\n constructor () {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 73171\n// gas irOptimized code: 291200\n// gas legacy: 83499\n// gas legacy code: 408800\n// f() -> -1, 1\n" + }, + "multiple_initializations.sol": { + "content": "contract A {\n uint immutable x = x + 1;\n uint immutable y = x += 2;\n\n constructor(uint) m(x += 16) m(x += 32) {\n x += 64;\n x += 128;\n }\n\n modifier m(uint) {\n _;\n }\n\n function get() public returns (uint) {\n return x;\n }\n}\n\ncontract B is A(A.x += 8) {\n constructor(uint) {}\n}\n\ncontract C is B {\n constructor() B(x += 4) {}\n}\n// ----\n// get() -> 0xff\n" + }, + "internal_function_pointer.sol": { + "content": "contract C {\n\tfunction() internal view returns(uint256) immutable z;\n\tconstructor() {\n\t\tz = f;\n\t}\n\tfunction f() public view returns (uint256) {\n\t\treturn 7;\n\t}\n\tfunction callZ() public view returns (uint) {\n\t\treturn z();\n\t}\n}\n// ----\n// f() -> 7\n// callZ() -> 7\n" + }, + "immutable_signed.sol": { + "content": "contract C {\n int8 immutable a = -2;\n bytes2 immutable b = \"ab\";\n function() internal returns (uint) immutable f = g;\n function viaasm() view external returns (bytes32 x, bytes32 y) {\n int8 _a = a;\n bytes2 _b = b;\n assembly { x := _a y := _b }\n }\n function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "stub.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tconstructor() {\n\t\tx = 42;\n\t\ty = 23;\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// f() -> 84, 23\n" + }, + "uninitialized.sol": { + "content": "contract C {\n uint immutable u;\n bool immutable b;\n address immutable a;\n\n function get() public returns (uint, bool, address) {\n return (u, b, a);\n }\n}\n// ----\n// get() -> 0, false, 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/immutable_use_scratch/use_scratch.sol b/examples/test/semanticTests/immutable_use_scratch/use_scratch.sol new file mode 100644 index 00000000..432c3c20 --- /dev/null +++ b/examples/test/semanticTests/immutable_use_scratch/use_scratch.sol @@ -0,0 +1,25 @@ +contract C { + uint256 immutable x; + uint256 immutable y; + mapping(uint => uint) public m; + constructor(uint _a) { + x = 42; + y = 23; + m[_a] = 7; + new uint[](4); + + } + function f() public view returns (uint256, uint256) { + return (x+x,y); + } +} +// ---- +// constructor(): 3 -> +// gas irOptimized: 81194 +// gas irOptimized code: 42400 +// gas legacy: 88244 +// gas legacy code: 109400 +// gas legacyOptimized: 81858 +// gas legacyOptimized code: 55800 +// f() -> 84, 23 +// m(uint256): 3 -> 7 diff --git a/examples/test/semanticTests/immutable_use_scratch/use_scratch_standard_input.json b/examples/test/semanticTests/immutable_use_scratch/use_scratch_standard_input.json new file mode 100644 index 00000000..e1e1ade9 --- /dev/null +++ b/examples/test/semanticTests/immutable_use_scratch/use_scratch_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "increment_decrement.sol": { + "content": "contract C {\n int immutable x = 1;\n int immutable y = 3;\n\n constructor() {\n x--;\n --x;\n y++;\n ++y;\n --y;\n }\n\n function f() public view returns (int, int) {\n return (x, y);\n }\n}\n// ----\n// f() -> -1, 4\n" + }, + "small_types_in_reverse.sol": { + "content": "contract A {\n\tuint16 public immutable a;\n\tuint16 public immutable b;\n\tuint16 public immutable c;\n\tuint16[3] public x;\n\tconstructor() {\n\t\tc = 0xffff;\n\t\tb = 0x0f0f;\n\t\ta = 0x1234;\n\t\tx = [a, b, c];\n\t}\n}\n// ----\n// a() -> 4660\n// b() -> 0x0f0f\n// c() -> 0xffff\n// x(uint256): 0 -> 4660\n// x(uint256): 1 -> 0x0f0f\n// x(uint256): 2 -> 0xffff\n" + }, + "multi_creation.sol": { + "content": "contract A {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 7;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract B {\n\tuint immutable a;\n\tconstructor() {\n\t\ta = 5;\n\t}\n\tfunction f() public view returns (uint) { return a; }\n}\ncontract C {\n\tuint immutable a;\n\tuint public x;\n\tuint public y;\n\tconstructor() {\n\t\ta = 3;\n\t\tx = (new A()).f();\n\t\ty = (new B()).f();\n\t}\n\tfunction f() public returns (uint256, uint, uint) {\n\t\treturn (a, (new A()).f(), (new B()).f());\n\t}\n}\n// ----\n// f() -> 3, 7, 5\n// gas irOptimized: 86796\n// gas irOptimized code: 37200\n// gas legacy: 87727\n// gas legacy code: 60800\n// gas legacyOptimized: 86770\n// gas legacyOptimized code: 37200\n// x() -> 7\n// y() -> 5\n" + }, + "inheritance.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tconstructor() {\n\t\ta = 4;\n\t}\n}\ncontract B is A {\n\tuint8 immutable b;\n\tconstructor() {\n\t\tb = 3;\n\t}\n}\ncontract C is A {\n\tuint8 immutable c;\n\tconstructor() {\n\t\tc = 2;\n\t}\n}\ncontract D is B, C {\n\tuint8 immutable d;\n\n\tconstructor() {\n\t\td = 1;\n\t}\n\tfunction f() public view returns (uint256, uint256, uint, uint) {\n\t\treturn (a, b, c, d);\n\t}\n}\n// ----\n// f() -> 4, 3, 2, 1\n" + }, + "assign_from_immutables.sol": { + "content": "contract C {\n\tuint immutable public a;\n\tuint immutable public b;\n\tuint immutable public c;\n\tuint immutable public d;\n\n\tconstructor() {\n\t\ta = 1;\n\t\tb = a;\n\t\tc = b;\n\t\td = c;\n\t}\n}\n// ----\n// a() -> 1\n// b() -> 1\n// c() -> 1\n// d() -> 1\n" + }, + "read_in_ctor.sol": { + "content": "contract A {\n\tuint8 immutable a;\n\tuint8 x;\n\n\tconstructor() {\n\t\ta = 3;\n\t\tx = a;\n\t}\n\n\tfunction readX() public view returns (uint8) {\n\t\treturn x;\n\t}\n}\n// ----\n// readX() -> 3\n" + }, + "assign_at_declaration.sol": { + "content": "contract A {\n\tuint8 immutable a = 2;\n\tfunction f() public view returns (uint) {\n\t\treturn a;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "getter.sol": { + "content": "contract C {\n uint immutable public x = 1;\n}\n// ----\n// x() -> 1\n" + }, + "getter_call_in_constructor.sol": { + "content": "contract A {\n uint immutable public x = 1;\n uint public y;\n constructor() {\n y = this.x();\n }\n}\ncontract C {\n function f() public returns (bool) {\n try new A() { return false; }\n catch { return true; }\n }\n}\n// ====\n// EVMVersion: >=tangerineWhistle\n// ----\n// f() -> true\n" + }, + "use_scratch.sol": { + "content": "contract C {\n\tuint256 immutable x;\n\tuint256 immutable y;\n\tmapping(uint => uint) public m;\n\tconstructor(uint _a) {\n\t\tx = 42;\n\t\ty = 23;\n\t\tm[_a] = 7;\n\t\tnew uint[](4);\n\n\t}\n\tfunction f() public view returns (uint256, uint256) {\n\t\treturn (x+x,y);\n\t}\n}\n// ----\n// constructor(): 3 ->\n// gas irOptimized: 81194\n// gas irOptimized code: 42400\n// gas legacy: 88244\n// gas legacy code: 109400\n// gas legacyOptimized: 81858\n// gas legacyOptimized code: 55800\n// f() -> 84, 23\n// m(uint256): 3 -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_access_base_storage/access_base_storage.sol b/examples/test/semanticTests/inheritance_access_base_storage/access_base_storage.sol new file mode 100644 index 00000000..034e7c1d --- /dev/null +++ b/examples/test/semanticTests/inheritance_access_base_storage/access_base_storage.sol @@ -0,0 +1,27 @@ +contract Base { + uint256 dataBase; + + function getViaBase() public returns (uint256 i) { + return dataBase; + } +} + + +contract Derived is Base { + uint256 dataDerived; + + function setData(uint256 base, uint256 derived) public returns (bool r) { + dataBase = base; + dataDerived = derived; + return true; + } + + function getViaDerived() public returns (uint256 base, uint256 derived) { + base = dataBase; + derived = dataDerived; + } +} +// ---- +// setData(uint256,uint256): 1, 2 -> true +// getViaBase() -> 1 +// getViaDerived() -> 1, 2 diff --git a/examples/test/semanticTests/inheritance_access_base_storage/access_base_storage_standard_input.json b/examples/test/semanticTests/inheritance_access_base_storage/access_base_storage_standard_input.json new file mode 100644 index 00000000..9285edb8 --- /dev/null +++ b/examples/test/semanticTests/inheritance_access_base_storage/access_base_storage_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution.sol b/examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution.sol new file mode 100644 index 00000000..0865ed28 --- /dev/null +++ b/examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution.sol @@ -0,0 +1,29 @@ +contract C { + function balance() public returns (uint256) { + return 1; + } + + function transfer(uint256 amount) public returns (uint256) { + return amount; + } +} + + +contract D { + function f() public returns (uint256) { + return (new C()).balance(); + } + + function g() public returns (uint256) { + return (new C()).transfer(5); + } +} +// ---- +// f() -> 1 +// gas irOptimized: 77051 +// gas legacy: 54480 +// gas legacy code: 57800 +// g() -> 5 +// gas irOptimized: 77106 +// gas legacy: 55016 +// gas legacy code: 57800 diff --git a/examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution_standard_input.json b/examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution_standard_input.json new file mode 100644 index 00000000..c6c6cd37 --- /dev/null +++ b/examples/test/semanticTests/inheritance_address_overload_resolution/address_overload_resolution_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables.sol b/examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables.sol new file mode 100644 index 00000000..9cff3c72 --- /dev/null +++ b/examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables.sol @@ -0,0 +1,20 @@ +contract C { + function() returns (uint256) internal x; + + function set() public { + C.x = g; + } + + function g() public pure returns (uint256) { + return 2; + } + + function h() public returns (uint256) { + return C.x(); + } +} +// ---- +// g() -> 2 +// h() -> FAILURE, hex"4e487b71", 0x51 +// set() -> +// h() -> 2 diff --git a/examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables_standard_input.json b/examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables_standard_input.json new file mode 100644 index 00000000..11893db5 --- /dev/null +++ b/examples/test/semanticTests/inheritance_base_access_to_function_type_variables/base_access_to_function_type_variables_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "super_overload.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f(bool b) public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return super.f(true);\n }\n\n function h() public returns (uint256) {\n return super.f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "value_for_constructor.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) payable {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() payable {\n h = (new Helper){value: 10}(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n\n function getBalances() public returns (uint256 me, uint256 them) {\n me = address(this).balance;\n them = address(h).balance;\n }\n}\n// ----\n// constructor(), 22 wei ->\n// gas irOptimized: 143864\n// gas irOptimized code: 118000\n// gas legacy: 156599\n// gas legacy code: 236400\n// gas legacyOptimized: 143592\n// gas legacyOptimized code: 118000\n// getFlag() -> true\n// getName() -> \"abc\"\n// getBalances() -> 12, 10\n" + }, + "base_access_to_function_type_variables.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n function set() public {\n C.x = g;\n }\n\n function g() public pure returns (uint256) {\n return 2;\n }\n\n function h() public returns (uint256) {\n return C.x();\n }\n}\n// ----\n// g() -> 2\n// h() -> FAILURE, hex\"4e487b71\", 0x51\n// set() ->\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata.sol b/examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata.sol new file mode 100644 index 00000000..4de95b0f --- /dev/null +++ b/examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata.sol @@ -0,0 +1,18 @@ +abstract contract A { + function f(uint256[] calldata a) external virtual returns (uint256[] calldata); +} + +contract B is A { + function f(uint256[] memory a) public override returns (uint256[] memory) { + return a; + } + + function g(uint[] calldata x) public returns (uint256[] memory) { + return f(x); + } +} +// ==== +// compileViaYul: also +// ---- +// f(uint256[]): 0x20, 2, 9, 8 -> 0x20, 2, 9, 8 +// g(uint256[]): 0x20, 2, 9, 8 -> 0x20, 2, 9, 8 diff --git a/examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata_standard_input.json b/examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata_standard_input.json new file mode 100644 index 00000000..1579ff8e --- /dev/null +++ b/examples/test/semanticTests/inheritance_dataLocation_external_public_calldata/external_public_calldata_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "external_public_calldata.sol": { + "content": "abstract contract A {\n function f(uint256[] calldata a) external virtual returns (uint256[] calldata);\n}\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256[] memory) {\n return a;\n }\n\n function g(uint[] calldata x) public returns (uint256[] memory) {\n return f(x);\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f(uint256[]): 0x20, 2, 9, 8 -> 0x20, 2, 9, 8\n// g(uint256[]): 0x20, 2, 9, 8 -> 0x20, 2, 9, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct.sol b/examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct.sol new file mode 100644 index 00000000..02e20c49 --- /dev/null +++ b/examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct.sol @@ -0,0 +1,18 @@ +contract B { + function f() public returns (uint256) { + return 10; + } +} + + +contract C is B { + function f(uint256 i) public returns (uint256) { + return 2 * i; + } + + function g() public returns (uint256) { + return f(1); + } +} +// ---- +// g() -> 2 diff --git a/examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct_standard_input.json b/examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct_standard_input.json new file mode 100644 index 00000000..7f29bef6 --- /dev/null +++ b/examples/test/semanticTests/inheritance_derived_overload_base_function_direct/derived_overload_base_function_direct_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect.sol b/examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect.sol new file mode 100644 index 00000000..5976fee6 --- /dev/null +++ b/examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect.sol @@ -0,0 +1,26 @@ +contract A { + function f(uint256 a) public returns (uint256) { + return 2 * a; + } +} + + +contract B { + function f() public returns (uint256) { + return 10; + } +} + + +contract C is A, B { + function g() public returns (uint256) { + return f(); + } + + function h() public returns (uint256) { + return f(1); + } +} +// ---- +// g() -> 10 +// h() -> 2 diff --git a/examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect_standard_input.json b/examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect_standard_input.json new file mode 100644 index 00000000..e7dd0dca --- /dev/null +++ b/examples/test/semanticTests/inheritance_derived_overload_base_function_indirect/derived_overload_base_function_indirect_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class.sol b/examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class.sol new file mode 100644 index 00000000..78f1f186 --- /dev/null +++ b/examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class.sol @@ -0,0 +1,26 @@ +contract BaseBase { + function g() public virtual returns (uint256 r) { + return 1; + } +} + + +contract Base is BaseBase { + function g() public virtual override returns (uint256 r) { + return 2; + } +} + + +contract Derived is Base { + function f() public returns (uint256 r) { + return BaseBase.g(); + } + + function g() public override returns (uint256 r) { + return 3; + } +} +// ---- +// g() -> 3 +// f() -> 1 diff --git a/examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class_standard_input.json b/examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class_standard_input.json new file mode 100644 index 00000000..cea8d946 --- /dev/null +++ b/examples/test/semanticTests/inheritance_explicit_base_class/explicit_base_class_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var.sol b/examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var.sol new file mode 100644 index 00000000..70674a6c --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var.sol @@ -0,0 +1,12 @@ +contract A { + uint256 constant x = 7; +} + + +contract B is A { + function f() public returns (uint256) { + return A.x; + } +} +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var_standard_input.json b/examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var_standard_input.json new file mode 100644 index 00000000..1a7c77d5 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_constant_state_var/inherited_constant_state_var_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_function/inherited_function.sol b/examples/test/semanticTests/inheritance_inherited_function/inherited_function.sol new file mode 100644 index 00000000..fb3f8ee8 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function/inherited_function.sol @@ -0,0 +1,18 @@ +contract A { + function f() internal virtual returns (uint256) { + return 1; + } +} + + +contract B is A { + function f() internal override returns (uint256) { + return 2; + } + + function g() public returns (uint256) { + return A.f(); + } +} +// ---- +// g() -> 1 diff --git a/examples/test/semanticTests/inheritance_inherited_function/inherited_function_standard_input.json b/examples/test/semanticTests/inheritance_inherited_function/inherited_function_standard_input.json new file mode 100644 index 00000000..3412ff0c --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function/inherited_function_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface.sol b/examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface.sol new file mode 100644 index 00000000..f64a2e12 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface.sol @@ -0,0 +1,27 @@ +interface I { + function f(uint256[] calldata a) external returns (uint256); +} + + +contract A is I { + function f(uint256[] calldata a) external override returns (uint256) { + return 42; + } +} + + +contract B { + function f(uint256[] memory a) public returns (uint256) { + return a[1]; + } + + function g() public returns (uint256) { + I i = I(new A()); + return i.f(new uint256[](2)); + } +} +// ---- +// g() -> 42 +// gas irOptimized: 80813 +// gas legacy: 55868 +// gas legacy code: 66600 diff --git a/examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface_standard_input.json b/examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface_standard_input.json new file mode 100644 index 00000000..1225ba6c --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_calldata_calldata_interface/inherited_function_calldata_calldata_interface_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory.sol b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory.sol new file mode 100644 index 00000000..a6274ed7 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory.sol @@ -0,0 +1,21 @@ +contract A { + function f(uint256[] calldata a) external virtual returns (uint256) { + return a[0]; + } +} + + +contract B is A { + function f(uint256[] memory a) public override returns (uint256) { + return a[1]; + } + + function g() public returns (uint256) { + uint256[] memory m = new uint256[](2); + m[0] = 42; + m[1] = 23; + return A(this).f(m); + } +} +// ---- +// g() -> 23 diff --git a/examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory_standard_input.json b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory_standard_input.json new file mode 100644 index 00000000..55be45ab --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory/inherited_function_calldata_memory_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface.sol b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface.sol new file mode 100644 index 00000000..07beb2c5 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface.sol @@ -0,0 +1,29 @@ +interface I { + function f(uint256[] calldata a) external returns (uint256); +} + + +contract A is I { + function f(uint256[] memory a) public override returns (uint256) { + return 42; + } +} + + +contract B { + function f(uint256[] memory a) public returns (uint256) { + return a[1]; + } + + function g() public returns (uint256) { + I i = I(new A()); + return i.f(new uint256[](2)); + } +} +// ---- +// g() -> 42 +// gas irOptimized: 100282 +// gas legacy: 56839 +// gas legacy code: 123600 +// gas legacyOptimized: 55001 +// gas legacyOptimized code: 60600 diff --git a/examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface_standard_input.json b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface_standard_input.json new file mode 100644 index 00000000..00210ad3 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_calldata_memory_interface/inherited_function_calldata_memory_interface_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library.sol b/examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library.sol new file mode 100644 index 00000000..1b1092cb --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library.sol @@ -0,0 +1,18 @@ +library A { + function f() internal returns (uint256) { + return 1; + } +} + + +contract B { + function f() internal returns (uint256) { + return 2; + } + + function g() public returns (uint256) { + return A.f(); + } +} +// ---- +// g() -> 1 diff --git a/examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library_standard_input.json b/examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library_standard_input.json new file mode 100644 index 00000000..08f81fb6 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_from_a_library/inherited_function_from_a_library_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch.sol b/examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch.sol new file mode 100644 index 00000000..39683079 --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch.sol @@ -0,0 +1,19 @@ +contract A { + function f() internal virtual returns (uint256) { + return 1; + } +} + + +contract B is A { + function f() internal override returns (uint256) { + return 2; + } + + function g() public returns (uint256) { + function() internal returns (uint256) ptr = A.f; + return ptr(); + } +} +// ---- +// g() -> 1 diff --git a/examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch_standard_input.json b/examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch_standard_input.json new file mode 100644 index 00000000..294540cd --- /dev/null +++ b/examples/test/semanticTests/inheritance_inherited_function_through_dispatch/inherited_function_through_dispatch_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor.sol b/examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor.sol new file mode 100644 index 00000000..b9697c5a --- /dev/null +++ b/examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor.sol @@ -0,0 +1,26 @@ +==== Source: A ==== +contract C { + int private x; + constructor (int p) public { x = p; } + function getX() public returns (int) { return x; } +} +==== Source: B ==== +import "A" as M; + +contract D is M.C { + constructor (int p) M.C(p) public {} +} + +contract A { + function g(int p) public returns (int) { + D d = new D(p); + return d.getX(); + } +} +// ---- +// g(int256): -1 -> -1 +// gas legacy: 77876 +// gas legacy code: 24200 +// g(int256): 10 -> 10 +// gas legacy: 77504 +// gas legacy code: 24200 diff --git a/examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor_standard_input.json b/examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor_standard_input.json new file mode 100644 index 00000000..ec96565f --- /dev/null +++ b/examples/test/semanticTests/inheritance_member_notation_ctor/member_notation_ctor_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first.sol b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first.sol new file mode 100644 index 00000000..d31dba48 --- /dev/null +++ b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first.sol @@ -0,0 +1,15 @@ +contract test { + function f(uint256 k) public returns (uint256 d) { + return k; + } + + function f(uint256 a, uint256 b) public returns (uint256 d) { + return a + b; + } + + function g() public returns (uint256 d) { + return f(3); + } +} +// ---- +// g() -> 3 diff --git a/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first_standard_input.json b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first_standard_input.json new file mode 100644 index 00000000..b64ba40a --- /dev/null +++ b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_first/overloaded_function_call_resolve_to_first_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second.sol b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second.sol new file mode 100644 index 00000000..c1f816c1 --- /dev/null +++ b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second.sol @@ -0,0 +1,15 @@ +contract test { + function f(uint256 a, uint256 b) public returns (uint256 d) { + return a + b; + } + + function f(uint256 k) public returns (uint256 d) { + return k; + } + + function g() public returns (uint256 d) { + return f(3, 7); + } +} +// ---- +// g() -> 10 diff --git a/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second_standard_input.json b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second_standard_input.json new file mode 100644 index 00000000..4a5032d3 --- /dev/null +++ b/examples/test/semanticTests/inheritance_overloaded_function_call_resolve_to_second/overloaded_function_call_resolve_to_second_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "super_overload.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f(bool b) public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return super.f(true);\n }\n\n function h() public returns (uint256) {\n return super.f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "value_for_constructor.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) payable {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() payable {\n h = (new Helper){value: 10}(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n\n function getBalances() public returns (uint256 me, uint256 them) {\n me = address(this).balance;\n them = address(h).balance;\n }\n}\n// ----\n// constructor(), 22 wei ->\n// gas irOptimized: 143864\n// gas irOptimized code: 118000\n// gas legacy: 156599\n// gas legacy code: 236400\n// gas legacyOptimized: 143592\n// gas legacyOptimized code: 118000\n// getFlag() -> true\n// getName() -> \"abc\"\n// getBalances() -> 12, 10\n" + }, + "base_access_to_function_type_variables.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n function set() public {\n C.x = g;\n }\n\n function g() public pure returns (uint256) {\n return 2;\n }\n\n function h() public returns (uint256) {\n return C.x();\n }\n}\n// ----\n// g() -> 2\n// h() -> FAILURE, hex\"4e487b71\", 0x51\n// set() ->\n// h() -> 2\n" + }, + "super_in_constructor_assignment.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n function() internal returns (uint) x = super.f;\n return x() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n function() internal returns (uint) x = super.f;\n return x() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n function() internal returns (uint) x = super.f;\n data = x() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "overloaded_function_call_resolve_to_second.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g() public returns (uint256 d) {\n return f(3, 7);\n }\n}\n// ----\n// g() -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else.sol b/examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else.sol new file mode 100644 index 00000000..c0ff8fd5 --- /dev/null +++ b/examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else.sol @@ -0,0 +1,17 @@ +contract test { + function f(uint256 a, uint256 b) public returns (uint256 d) { + return a + b; + } + + function f(uint256 k) public returns (uint256 d) { + return k; + } + + function g(bool flag) public returns (uint256 d) { + if (flag) return f(3); + else return f(3, 7); + } +} +// ---- +// g(bool): true -> 3 +// g(bool): false -> 10 diff --git a/examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else_standard_input.json b/examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else_standard_input.json new file mode 100644 index 00000000..871f275d --- /dev/null +++ b/examples/test/semanticTests/inheritance_overloaded_function_call_with_if_else/overloaded_function_call_with_if_else_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base.sol b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base.sol new file mode 100644 index 00000000..7b8af54e --- /dev/null +++ b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base.sol @@ -0,0 +1,18 @@ +contract Base { + constructor(uint256 i) { + m_i = i; + } + + uint256 public m_i; +} + + +contract Derived is Base { + constructor(uint256 i) Base(i) {} +} + + +contract Final is Derived(4) {} + +// ---- +// m_i() -> 4 diff --git a/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base_standard_input.json b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base_standard_input.json new file mode 100644 index 00000000..203344ca --- /dev/null +++ b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base/pass_dynamic_arguments_to_the_base_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base.sol b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base.sol new file mode 100644 index 00000000..d028630e --- /dev/null +++ b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base.sol @@ -0,0 +1,23 @@ +contract Base { + constructor(uint256 j) { + m_i = j; + } + + uint256 public m_i; +} + + +contract Base1 is Base { + constructor(uint256 k) Base(k) {} +} + + +contract Derived is Base, Base1 { + constructor(uint256 i) Base1(i) {} +} + + +contract Final is Derived(4) {} + +// ---- +// m_i() -> 4 diff --git a/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base_standard_input.json b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base_standard_input.json new file mode 100644 index 00000000..c2dfb0fb --- /dev/null +++ b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base/pass_dynamic_arguments_to_the_base_base_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap.sol b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap.sol new file mode 100644 index 00000000..221368f0 --- /dev/null +++ b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap.sol @@ -0,0 +1,23 @@ +contract Base { + constructor(uint256 i) { + m_i = i; + } + + uint256 public m_i; +} + + +abstract contract Base1 is Base { + constructor(uint256 k) {} +} + + +contract Derived is Base, Base1 { + constructor(uint256 i) Base(i) Base1(7) {} +} + + +contract Final is Derived(4) {} + +// ---- +// m_i() -> 4 diff --git a/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap_standard_input.json b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap_standard_input.json new file mode 100644 index 00000000..08c99cf8 --- /dev/null +++ b/examples/test/semanticTests/inheritance_pass_dynamic_arguments_to_the_base_base_with_gap/pass_dynamic_arguments_to_the_base_base_with_gap_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor.sol b/examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor.sol new file mode 100644 index 00000000..7e0aa51d --- /dev/null +++ b/examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor.sol @@ -0,0 +1,34 @@ +contract A { + function f() public virtual returns (uint256 r) { + return 1; + } +} + + +contract B is A { + function f() public virtual override returns (uint256 r) { + return super.f() | 2; + } +} + + +contract C is A { + function f() public virtual override returns (uint256 r) { + return super.f() | 4; + } +} + + +contract D is B, C { + uint256 data; + + constructor() { + data = super.f() | 8; + } + + function f() public override (B, C) returns (uint256 r) { + return data; + } +} +// ---- +// f() -> 15 diff --git a/examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor_standard_input.json b/examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor_standard_input.json new file mode 100644 index 00000000..1d0c482e --- /dev/null +++ b/examples/test/semanticTests/inheritance_super_in_constructor/super_in_constructor_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment.sol b/examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment.sol new file mode 100644 index 00000000..6b06a784 --- /dev/null +++ b/examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment.sol @@ -0,0 +1,37 @@ +contract A { + function f() public virtual returns (uint256 r) { + return 1; + } +} + + +contract B is A { + function f() public virtual override returns (uint256 r) { + function() internal returns (uint) x = super.f; + return x() | 2; + } +} + + +contract C is A { + function f() public virtual override returns (uint256 r) { + function() internal returns (uint) x = super.f; + return x() | 4; + } +} + + +contract D is B, C { + uint256 data; + + constructor() { + function() internal returns (uint) x = super.f; + data = x() | 8; + } + + function f() public override (B, C) returns (uint256 r) { + return data; + } +} +// ---- +// f() -> 15 diff --git a/examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment_standard_input.json b/examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment_standard_input.json new file mode 100644 index 00000000..8deb0152 --- /dev/null +++ b/examples/test/semanticTests/inheritance_super_in_constructor_assignment/super_in_constructor_assignment_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "super_overload.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f(bool b) public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return super.f(true);\n }\n\n function h() public returns (uint256) {\n return super.f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "value_for_constructor.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) payable {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() payable {\n h = (new Helper){value: 10}(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n\n function getBalances() public returns (uint256 me, uint256 them) {\n me = address(this).balance;\n them = address(h).balance;\n }\n}\n// ----\n// constructor(), 22 wei ->\n// gas irOptimized: 143864\n// gas irOptimized code: 118000\n// gas legacy: 156599\n// gas legacy code: 236400\n// gas legacyOptimized: 143592\n// gas legacyOptimized code: 118000\n// getFlag() -> true\n// getName() -> \"abc\"\n// getBalances() -> 12, 10\n" + }, + "base_access_to_function_type_variables.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n function set() public {\n C.x = g;\n }\n\n function g() public pure returns (uint256) {\n return 2;\n }\n\n function h() public returns (uint256) {\n return C.x();\n }\n}\n// ----\n// g() -> 2\n// h() -> FAILURE, hex\"4e487b71\", 0x51\n// set() ->\n// h() -> 2\n" + }, + "super_in_constructor_assignment.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n function() internal returns (uint) x = super.f;\n return x() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n function() internal returns (uint) x = super.f;\n return x() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n function() internal returns (uint) x = super.f;\n data = x() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_super_overload/super_overload.sol b/examples/test/semanticTests/inheritance_super_overload/super_overload.sol new file mode 100644 index 00000000..7b0b1448 --- /dev/null +++ b/examples/test/semanticTests/inheritance_super_overload/super_overload.sol @@ -0,0 +1,26 @@ +contract A { + function f(uint256 a) public returns (uint256) { + return 2 * a; + } +} + + +contract B { + function f(bool b) public returns (uint256) { + return 10; + } +} + + +contract C is A, B { + function g() public returns (uint256) { + return super.f(true); + } + + function h() public returns (uint256) { + return super.f(1); + } +} +// ---- +// g() -> 10 +// h() -> 2 diff --git a/examples/test/semanticTests/inheritance_super_overload/super_overload_standard_input.json b/examples/test/semanticTests/inheritance_super_overload/super_overload_standard_input.json new file mode 100644 index 00000000..bd556663 --- /dev/null +++ b/examples/test/semanticTests/inheritance_super_overload/super_overload_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "super_overload.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f(bool b) public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return super.f(true);\n }\n\n function h() public returns (uint256) {\n return super.f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable.sol b/examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable.sol new file mode 100644 index 00000000..cef016bc --- /dev/null +++ b/examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable.sol @@ -0,0 +1,22 @@ +contract A { + uint24 transient x; + int24 y; +} + +contract C is A { + uint24 w; + int24 transient z; + + function f() public returns (uint24, int24, uint24, int24) { + x += 1; + y += 2; + w += 3; + z += 4; + + return (x, y, w, z); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1, 2, 3, 4 diff --git a/examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable_standard_input.json b/examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable_standard_input.json new file mode 100644 index 00000000..9f21629b --- /dev/null +++ b/examples/test/semanticTests/inheritance_transient_storage_state_variable/transient_storage_state_variable_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "super_overload.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f(bool b) public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return super.f(true);\n }\n\n function h() public returns (uint256) {\n return super.f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "value_for_constructor.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) payable {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() payable {\n h = (new Helper){value: 10}(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n\n function getBalances() public returns (uint256 me, uint256 them) {\n me = address(this).balance;\n them = address(h).balance;\n }\n}\n// ----\n// constructor(), 22 wei ->\n// gas irOptimized: 143864\n// gas irOptimized code: 118000\n// gas legacy: 156599\n// gas legacy code: 236400\n// gas legacyOptimized: 143592\n// gas legacyOptimized code: 118000\n// getFlag() -> true\n// getName() -> \"abc\"\n// getBalances() -> 12, 10\n" + }, + "base_access_to_function_type_variables.sol": { + "content": "contract C {\n function() returns (uint256) internal x;\n\n function set() public {\n C.x = g;\n }\n\n function g() public pure returns (uint256) {\n return 2;\n }\n\n function h() public returns (uint256) {\n return C.x();\n }\n}\n// ----\n// g() -> 2\n// h() -> FAILURE, hex\"4e487b71\", 0x51\n// set() ->\n// h() -> 2\n" + }, + "super_in_constructor_assignment.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n function() internal returns (uint) x = super.f;\n return x() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n function() internal returns (uint) x = super.f;\n return x() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n function() internal returns (uint) x = super.f;\n data = x() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "overloaded_function_call_resolve_to_second.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g() public returns (uint256 d) {\n return f(3, 7);\n }\n}\n// ----\n// g() -> 10\n" + }, + "transient_storage_state_variable.sol": { + "content": "contract A {\n uint24 transient x;\n int24 y;\n}\n\ncontract C is A {\n uint24 w;\n int24 transient z;\n\n function f() public returns (uint24, int24, uint24, int24) {\n x += 1;\n y += 2;\n w += 3;\n z += 4;\n\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract.sol b/examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract.sol new file mode 100644 index 00000000..5db209f1 --- /dev/null +++ b/examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract.sol @@ -0,0 +1,26 @@ +abstract contract A { + uint transient x; + int y; + function f() public virtual returns (uint, int, uint, int); +} + +contract C is A { + uint w; + int transient z; + + function g() public { + w += 2; + z += 2; + } + + function f() public override returns (uint, int, uint, int) { + x += 1; + y += 1; + g(); + return (x, y, w, z); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1, 1, 2, 2 diff --git a/examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract_standard_input.json b/examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract_standard_input.json new file mode 100644 index 00000000..c55cf2db --- /dev/null +++ b/examples/test/semanticTests/inheritance_transient_storage_state_variable_abstract_contract/transient_storage_state_variable_abstract_contract_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor.sol b/examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor.sol new file mode 100644 index 00000000..39b25c00 --- /dev/null +++ b/examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor.sol @@ -0,0 +1,50 @@ +contract Helper { + bytes3 name; + bool flag; + + constructor(bytes3 x, bool f) payable { + name = x; + flag = f; + } + + function getName() public returns (bytes3 ret) { + return name; + } + + function getFlag() public returns (bool ret) { + return flag; + } +} + + +contract Main { + Helper h; + + constructor() payable { + h = (new Helper){value: 10}("abc", true); + } + + function getFlag() public returns (bool ret) { + return h.getFlag(); + } + + function getName() public returns (bytes3 ret) { + return h.getName(); + } + + function getBalances() public returns (uint256 me, uint256 them) { + me = address(this).balance; + them = address(h).balance; + } +} +// ---- +// constructor(), 22 wei -> +// gas irOptimized: 143864 +// gas irOptimized code: 118000 +// gas legacy: 156599 +// gas legacy code: 236400 +// gas legacyOptimized: 143592 +// gas legacyOptimized code: 118000 +// getFlag() -> true +// getName() -> "abc" +// getBalances() -> 12, 10 diff --git a/examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor_standard_input.json b/examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor_standard_input.json new file mode 100644 index 00000000..cfc3564d --- /dev/null +++ b/examples/test/semanticTests/inheritance_value_for_constructor/value_for_constructor_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "explicit_base_class.sol": { + "content": "contract BaseBase {\n function g() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract Base is BaseBase {\n function g() public virtual override returns (uint256 r) {\n return 2;\n }\n}\n\n\ncontract Derived is Base {\n function f() public returns (uint256 r) {\n return BaseBase.g();\n }\n\n function g() public override returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// g() -> 3\n// f() -> 1\n" + }, + "member_notation_ctor.sol": { + "content": "==== Source: A ====\ncontract C {\n\tint private x;\n\tconstructor (int p) public { x = p; }\n\tfunction getX() public returns (int) { return x; }\n}\n==== Source: B ====\nimport \"A\" as M;\n\ncontract D is M.C {\n\tconstructor (int p) M.C(p) public {}\n}\n\ncontract A {\n\tfunction g(int p) public returns (int) {\n\t\tD d = new D(p);\n\t\treturn d.getX();\n\t}\n}\n// ----\n// g(int256): -1 -> -1\n// gas legacy: 77876\n// gas legacy code: 24200\n// g(int256): 10 -> 10\n// gas legacy: 77504\n// gas legacy code: 24200\n" + }, + "inherited_function_through_dispatch.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n function() internal returns (uint256) ptr = A.f;\n return ptr();\n }\n}\n// ----\n// g() -> 1\n" + }, + "access_base_storage.sol": { + "content": "contract Base {\n uint256 dataBase;\n\n function getViaBase() public returns (uint256 i) {\n return dataBase;\n }\n}\n\n\ncontract Derived is Base {\n uint256 dataDerived;\n\n function setData(uint256 base, uint256 derived) public returns (bool r) {\n dataBase = base;\n dataDerived = derived;\n return true;\n }\n\n function getViaDerived() public returns (uint256 base, uint256 derived) {\n base = dataBase;\n derived = dataDerived;\n }\n}\n// ----\n// setData(uint256,uint256): 1, 2 -> true\n// getViaBase() -> 1\n// getViaDerived() -> 1, 2\n" + }, + "derived_overload_base_function_direct.sol": { + "content": "contract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is B {\n function f(uint256 i) public returns (uint256) {\n return 2 * i;\n }\n\n function g() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 2\n" + }, + "address_overload_resolution.sol": { + "content": "contract C {\n function balance() public returns (uint256) {\n return 1;\n }\n\n function transfer(uint256 amount) public returns (uint256) {\n return amount;\n }\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).balance();\n }\n\n function g() public returns (uint256) {\n return (new C()).transfer(5);\n }\n}\n// ----\n// f() -> 1\n// gas irOptimized: 77051\n// gas legacy: 54480\n// gas legacy code: 57800\n// g() -> 5\n// gas irOptimized: 77106\n// gas legacy: 55016\n// gas legacy code: 57800\n" + }, + "pass_dynamic_arguments_to_the_base_base_with_gap.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\nabstract contract Base1 is Base {\n constructor(uint256 k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base(i) Base1(7) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "inherited_constant_state_var.sol": { + "content": "contract A {\n uint256 constant x = 7;\n}\n\n\ncontract B is A {\n function f() public returns (uint256) {\n return A.x;\n }\n}\n// ----\n// f() -> 7\n" + }, + "overloaded_function_call_resolve_to_first.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function g() public returns (uint256 d) {\n return f(3);\n }\n}\n// ----\n// g() -> 3\n" + }, + "super_in_constructor.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n uint256 data;\n\n constructor() {\n data = super.f() | 8;\n }\n\n function f() public override (B, C) returns (uint256 r) {\n return data;\n }\n}\n// ----\n// f() -> 15\n" + }, + "inherited_function_calldata_memory.sol": { + "content": "contract A {\n function f(uint256[] calldata a) external virtual returns (uint256) {\n return a[0];\n }\n}\n\n\ncontract B is A {\n function f(uint256[] memory a) public override returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n uint256[] memory m = new uint256[](2);\n m[0] = 42;\n m[1] = 23;\n return A(this).f(m);\n }\n}\n// ----\n// g() -> 23\n" + }, + "inherited_function_calldata_calldata_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] calldata a) external override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 80813\n// gas legacy: 55868\n// gas legacy code: 66600\n" + }, + "transient_storage_state_variable_abstract_contract.sol": { + "content": "abstract contract A {\n uint transient x;\n int y;\n function f() public virtual returns (uint, int, uint, int);\n}\n\ncontract C is A {\n uint w;\n int transient z;\n\n function g() public {\n w += 2;\n z += 2;\n }\n\n function f() public override returns (uint, int, uint, int) {\n x += 1;\n y += 1;\n g();\n return (x, y, w, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 1, 2, 2\n" + }, + "inherited_function.sol": { + "content": "contract A {\n function f() internal virtual returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() internal override returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "pass_dynamic_arguments_to_the_base.sol": { + "content": "contract Base {\n constructor(uint256 i) {\n m_i = i;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Derived is Base {\n constructor(uint256 i) Base(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "overloaded_function_call_with_if_else.sol": { + "content": "contract test {\n function f(uint256 a, uint256 b) public returns (uint256 d) {\n return a + b;\n }\n\n function f(uint256 k) public returns (uint256 d) {\n return k;\n }\n\n function g(bool flag) public returns (uint256 d) {\n if (flag) return f(3);\n else return f(3, 7);\n }\n}\n// ----\n// g(bool): true -> 3\n// g(bool): false -> 10\n" + }, + "inherited_function_from_a_library.sol": { + "content": "library A {\n function f() internal returns (uint256) {\n return 1;\n }\n}\n\n\ncontract B {\n function f() internal returns (uint256) {\n return 2;\n }\n\n function g() public returns (uint256) {\n return A.f();\n }\n}\n// ----\n// g() -> 1\n" + }, + "inherited_function_calldata_memory_interface.sol": { + "content": "interface I {\n function f(uint256[] calldata a) external returns (uint256);\n}\n\n\ncontract A is I {\n function f(uint256[] memory a) public override returns (uint256) {\n return 42;\n }\n}\n\n\ncontract B {\n function f(uint256[] memory a) public returns (uint256) {\n return a[1];\n }\n\n function g() public returns (uint256) {\n I i = I(new A());\n return i.f(new uint256[](2));\n }\n}\n// ----\n// g() -> 42\n// gas irOptimized: 100282\n// gas legacy: 56839\n// gas legacy code: 123600\n// gas legacyOptimized: 55001\n// gas legacyOptimized code: 60600\n" + }, + "pass_dynamic_arguments_to_the_base_base.sol": { + "content": "contract Base {\n constructor(uint256 j) {\n m_i = j;\n }\n\n uint256 public m_i;\n}\n\n\ncontract Base1 is Base {\n constructor(uint256 k) Base(k) {}\n}\n\n\ncontract Derived is Base, Base1 {\n constructor(uint256 i) Base1(i) {}\n}\n\n\ncontract Final is Derived(4) {}\n\n// ----\n// m_i() -> 4\n" + }, + "derived_overload_base_function_indirect.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f() public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return f();\n }\n\n function h() public returns (uint256) {\n return f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "super_overload.sol": { + "content": "contract A {\n function f(uint256 a) public returns (uint256) {\n return 2 * a;\n }\n}\n\n\ncontract B {\n function f(bool b) public returns (uint256) {\n return 10;\n }\n}\n\n\ncontract C is A, B {\n function g() public returns (uint256) {\n return super.f(true);\n }\n\n function h() public returns (uint256) {\n return super.f(1);\n }\n}\n// ----\n// g() -> 10\n// h() -> 2\n" + }, + "value_for_constructor.sol": { + "content": "contract Helper {\n bytes3 name;\n bool flag;\n\n constructor(bytes3 x, bool f) payable {\n name = x;\n flag = f;\n }\n\n function getName() public returns (bytes3 ret) {\n return name;\n }\n\n function getFlag() public returns (bool ret) {\n return flag;\n }\n}\n\n\ncontract Main {\n Helper h;\n\n constructor() payable {\n h = (new Helper){value: 10}(\"abc\", true);\n }\n\n function getFlag() public returns (bool ret) {\n return h.getFlag();\n }\n\n function getName() public returns (bytes3 ret) {\n return h.getName();\n }\n\n function getBalances() public returns (uint256 me, uint256 them) {\n me = address(this).balance;\n them = address(h).balance;\n }\n}\n// ----\n// constructor(), 22 wei ->\n// gas irOptimized: 143864\n// gas irOptimized code: 118000\n// gas legacy: 156599\n// gas legacy code: 236400\n// gas legacyOptimized: 143592\n// gas legacyOptimized code: 118000\n// getFlag() -> true\n// getName() -> \"abc\"\n// getBalances() -> 12, 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function.sol b/examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function.sol new file mode 100644 index 00000000..aba6b44b --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function.sol @@ -0,0 +1,21 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let basefee := sload(0) + ret := basefee + } + } + function g() public pure returns (uint ret) { + assembly { + function basefee() -> r { + r := 1000 + } + ret := basefee() + } + } +} +// ==== +// EVMVersion: <=berlin +// ---- +// f() -> 0 +// g() -> 1000 diff --git a/examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function_standard_input.json b/examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function_standard_input.json new file mode 100644 index 00000000..a9f1b03d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_basefee_berlin_function/basefee_berlin_function_standard_input.json @@ -0,0 +1,199 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function.sol b/examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function.sol new file mode 100644 index 00000000..d0645713 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function.sol @@ -0,0 +1,21 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let blobbasefee := 999 + ret := blobbasefee + } + } + function g() public pure returns (uint ret) { + assembly { + function blobbasefee() -> r { + r := 1000 + } + ret := blobbasefee() + } + } +} +// ==== +// EVMVersion: <=shanghai +// ---- +// f() -> 999 +// g() -> 1000 diff --git a/examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function_standard_input.json b/examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function_standard_input.json new file mode 100644 index 00000000..c6c919bb --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobbasefee_shanghai_function/blobbasefee_shanghai_function_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_blobhash/blobhash.sol b/examples/test/semanticTests/inlineAssembly_blobhash/blobhash.sol new file mode 100644 index 00000000..3beac1d2 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobhash/blobhash.sol @@ -0,0 +1,11 @@ +contract C { + function f() public view returns (bytes32 ret) { + assembly { + ret := blobhash(0) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001 diff --git a/examples/test/semanticTests/inlineAssembly_blobhash/blobhash_standard_input.json b/examples/test/semanticTests/inlineAssembly_blobhash/blobhash_standard_input.json new file mode 100644 index 00000000..806d0226 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobhash/blobhash_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count.sol b/examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count.sol new file mode 100644 index 00000000..7063978c --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count.sol @@ -0,0 +1,14 @@ +contract C { + function f() public view returns (bytes32 ret) { + assembly { + // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0. + // Thus, as we injected only two blob hashes in the transaction context in EVMHost, + // the return value of the function below MUST be zero. + ret := blobhash(2) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0x00 diff --git a/examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count_standard_input.json b/examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count_standard_input.json new file mode 100644 index 00000000..8815ce9a --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobhash_index_exceeding_blob_count/blobhash_index_exceeding_blob_count_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun.sol b/examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun.sol new file mode 100644 index 00000000..d3a41fc0 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun.sol @@ -0,0 +1,21 @@ +contract C { + function f() public pure returns (uint ret) { + assembly { + let blobhash := 1 + ret := blobhash + } + } + function g() public pure returns (uint ret) { + assembly { + function blobhash() -> r { + r := 1000 + } + ret := blobhash() + } + } +} +// ==== +// EVMVersion: 1 +// g() -> 1000 diff --git a/examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun_standard_input.json b/examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun_standard_input.json new file mode 100644 index 00000000..cf8b8c43 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_blobhash_pre_cancun/blobhash_pre_cancun_standard_input.json @@ -0,0 +1,229 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic.sol b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic.sol new file mode 100644 index 00000000..631e61fe --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint[2][] calldata x) public returns (uint[2][] memory r) { + assembly { x.offset := 0x44 x.length := 2 } + r = x; + } +} +// ---- +// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic_standard_input.json new file mode 100644 index 00000000..867d4882 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_dynamic/calldata_array_assign_dynamic_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static.sol b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static.sol new file mode 100644 index 00000000..32931be1 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) { + assembly { x := 0x24 } + r = x; + } +} +// ---- +// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static_standard_input.json new file mode 100644 index 00000000..ba63db1e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_array_assign_static/calldata_array_assign_static_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read.sol b/examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read.sol new file mode 100644 index 00000000..572e9def --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read.sol @@ -0,0 +1,10 @@ +contract C { + function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) { + assembly { l := x.length o := x.offset } + uint[2] calldata t = x[1]; + // statically-sized arrays only use one slot, so we read directly. + assembly { s := t } + } +} +// ---- +// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read_standard_input.json new file mode 100644 index 00000000..b4557482 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_array_read/calldata_array_read_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign.sol b/examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign.sol new file mode 100644 index 00000000..f5d557e5 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign.sol @@ -0,0 +1,8 @@ +contract C { + function f(bytes calldata x) public returns (bytes memory) { + assembly { x.offset := 1 x.length := 3 } + return x; + } +} +// ---- +// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign_standard_input.json new file mode 100644 index 00000000..4903ba77 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_assign/calldata_assign_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere.sol b/examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere.sol new file mode 100644 index 00000000..876fffd4 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure returns (bytes calldata x) { + assembly { x.offset := 0 x.length := 4 } + } +} +// ---- +// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere_standard_input.json new file mode 100644 index 00000000..9368bd6e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_assign_from_nowhere/calldata_assign_from_nowhere_standard_input.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read.sol b/examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read.sol new file mode 100644 index 00000000..d3574806 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read.sol @@ -0,0 +1,16 @@ +contract C { + function lenBytesRead(bytes calldata x) public returns (uint l) { + assembly { l := x.length } + } + + function lenStringRead(string calldata x) public returns (uint l) { + assembly { l := x.length } + } +} +// ---- +// lenBytesRead(bytes): 0x20, 4, "abcd" -> 4 +// lenBytesRead(bytes): 0x20, 0, "abcd" -> 0x00 +// lenBytesRead(bytes): 0x20, 0x21, "abcd", "ef" -> 33 +// lenStringRead(string): 0x20, 4, "abcd" -> 4 +// lenStringRead(string): 0x20, 0, "abcd" -> 0x00 +// lenStringRead(string): 0x20, 0x21, "abcd", "ef" -> 33 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read_standard_input.json new file mode 100644 index 00000000..b9f436c7 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_length_read/calldata_length_read_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read.sol b/examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read.sol new file mode 100644 index 00000000..0b10748c --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read.sol @@ -0,0 +1,17 @@ +contract C { + function f(bytes calldata x) public returns (uint r) { + assembly { r := x.offset } + } + + function f(uint, bytes calldata x, uint) public returns (uint r, uint v) { + assembly { + r := x.offset + v := x.length + } + } +} +// ---- +// f(bytes): 0x20, 0, 0 -> 0x44 +// f(bytes): 0x22, 0, 0, 0 -> 0x46 +// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2 +// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read_standard_input.json new file mode 100644 index 00000000..afa98124 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_offset_read/calldata_offset_read_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write.sol b/examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write.sol new file mode 100644 index 00000000..bcba7169 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write.sol @@ -0,0 +1,15 @@ +contract C { + function f(uint, bytes calldata x, uint) public returns (uint r, uint v) { + assembly { + x.offset := 8 + x.length := 20 + } + assembly { + r := x.offset + v := x.length + } + } +} +// ---- +// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14 +// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write_standard_input.json new file mode 100644 index 00000000..26cff109 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_offset_read_write/calldata_offset_read_write_standard_input.json @@ -0,0 +1,211 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign.sol b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign.sol new file mode 100644 index 00000000..96c01ae5 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + struct S { uint256 x; } + struct S2 { uint256 x; uint256 y; } + function f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) { + assembly { + s := s2 + s2 := 4 + } + r = s.x; + r2 = s2.x; + } +} +// ---- +// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42 diff --git a/examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign_standard_input.json new file mode 100644 index 00000000..4aeaaf35 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign/calldata_struct_assign_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return.sol b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return.sol new file mode 100644 index 00000000..4c699bc4 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; +contract C { + struct S { int8 x; int8 y; } + function f() internal pure returns(S calldata s) { + assembly { + s := 0x24 + } + } + function g() public pure returns(int8, int8) { + S calldata s = f(); + return (s.x, s.y); + } + function h() public pure returns(uint256) { f(); return 0x42; } + function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; } +} +// ---- +// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21 +// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE +// g(): 0xCAFFEE, 0x42 -> 0x42, 0 +// h() -> 0x42 +// i() -> FAILURE diff --git a/examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return_standard_input.json b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return_standard_input.json new file mode 100644 index 00000000..00d0e0be --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_calldata_struct_assign_and_return/calldata_struct_assign_and_return_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_chainid/chainid.sol b/examples/test/semanticTests/inlineAssembly_chainid/chainid.sol new file mode 100644 index 00000000..f93d87c9 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_chainid/chainid.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint id) { + assembly { + id := chainid() + } + } +} +// ==== +// EVMVersion: >=istanbul +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/inlineAssembly_chainid/chainid_standard_input.json b/examples/test/semanticTests/inlineAssembly_chainid/chainid_standard_input.json new file mode 100644 index 00000000..f179a933 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_chainid/chainid_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_constant_access/constant_access.sol b/examples/test/semanticTests/inlineAssembly_constant_access/constant_access.sol new file mode 100644 index 00000000..82badaca --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_constant_access/constant_access.sol @@ -0,0 +1,18 @@ +contract C { + uint constant a = 2; + bytes2 constant b = 0xabcd; + bytes3 constant c = "abc"; + bool constant d = true; + address constant e = 0x1212121212121212121212121212121212121212; + function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) { + assembly { + w := a + x := b + y := c + z := d + t := e + } + } +} +// ---- +// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212 diff --git a/examples/test/semanticTests/inlineAssembly_constant_access/constant_access_standard_input.json b/examples/test/semanticTests/inlineAssembly_constant_access/constant_access_standard_input.json new file mode 100644 index 00000000..e7e4bdcc --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_constant_access/constant_access_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing.sol b/examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing.sol new file mode 100644 index 00000000..d12a979c --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing.sol @@ -0,0 +1,26 @@ +contract C { + uint constant a = 2; + uint constant aa = a; + uint constant aaa = aa; + bytes2 constant b = 0xabcd; + bytes2 constant bb = b; + bytes3 constant c = "abc"; + bytes3 constant cc = c; + bytes3 constant ccc = cc; + bytes3 constant cccc = ccc; + bool constant d = true; + bool constant dd = d; + address constant e = 0x1212121212121212121212121212121212121212; + address constant ee = e; + function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) { + assembly { + w := aaa + x := bb + y := cccc + z := dd + t := ee + } + } +} +// ---- +// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212 diff --git a/examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing_standard_input.json b/examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing_standard_input.json new file mode 100644 index 00000000..cd586745 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_constant_access_referencing/constant_access_referencing_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_difficulty/difficulty.sol b/examples/test/semanticTests/inlineAssembly_difficulty/difficulty.sol new file mode 100644 index 00000000..ef531f78 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_difficulty/difficulty.sol @@ -0,0 +1,11 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + ret := difficulty() + } + } +} +// ==== +// EVMVersion: 200000000 diff --git a/examples/test/semanticTests/inlineAssembly_difficulty/difficulty_standard_input.json b/examples/test/semanticTests/inlineAssembly_difficulty/difficulty_standard_input.json new file mode 100644 index 00000000..eb053b01 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_difficulty/difficulty_standard_input.json @@ -0,0 +1,232 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address.sol b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address.sol new file mode 100644 index 00000000..ae891df5 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address.sol @@ -0,0 +1,17 @@ +contract C { + function testFunction() external {} + + function testYul() public returns (address adr) { + function() external fp = this.testFunction; + + assembly { + adr := fp.address + } + } + function testSol() public returns (address) { + return this.testFunction.address; + } +} +// ---- +// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address_standard_input.json b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address_standard_input.json new file mode 100644 index 00000000..dad7b019 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address/external_function_pointer_address_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment.sol b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment.sol new file mode 100644 index 00000000..eb28a6d2 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment.sol @@ -0,0 +1,16 @@ +contract C { + function testFunction() external {} + + function testYul(address newAddress) view public returns (address adr) { + function() external fp = this.testFunction; + + assembly { + fp.address := newAddress + } + + return fp.address; + } +} +// ---- +// testYul(address): 0x1234567890 -> 0x1234567890 +// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7 diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment_standard_input.json b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment_standard_input.json new file mode 100644 index 00000000..9da2acde --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_address_assignment/external_function_pointer_address_assignment_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector.sol b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector.sol new file mode 100644 index 00000000..2fa372f8 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector.sol @@ -0,0 +1,21 @@ +contract C { + function testFunction() external {} + + function testYul() public returns (uint32) { + function() external fp = this.testFunction; + uint selectorValue = 0; + + assembly { + selectorValue := fp.selector + } + + // Value is right-aligned, we shift it so it can be compared + return uint32(bytes4(bytes32(selectorValue << (256 - 32)))); + } + function testSol() public returns (uint32) { + return uint32(this.testFunction.selector); + } +} +// ---- +// testYul() -> 0xe16b4a9b +// testSol() -> 0xe16b4a9b diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector_standard_input.json b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector_standard_input.json new file mode 100644 index 00000000..d2cb5d76 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector/external_function_pointer_selector_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment.sol b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment.sol new file mode 100644 index 00000000..a8e88614 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment.sol @@ -0,0 +1,16 @@ +contract C { + function testFunction() external {} + + function testYul(uint32 newSelector) view public returns (uint32) { + function() external fp = this.testFunction; + + assembly { + fp.selector := newSelector + } + + return uint32(fp.selector); + } +} +// ---- +// testYul(uint32): 0x12345678 -> 0x12345678 +// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00 diff --git a/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment_standard_input.json b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment_standard_input.json new file mode 100644 index 00000000..43cd53f8 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_function_pointer_selector_assignment/external_function_pointer_selector_assignment_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing.sol b/examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing.sol new file mode 100644 index 00000000..19a4fbdb --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint x) { + assembly { + function g() -> f { f := 2 } + x := g() + } + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing_standard_input.json b/examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing_standard_input.json new file mode 100644 index 00000000..882979f5 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_external_identifier_access_shadowing/external_identifier_access_shadowing_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash.sol b/examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash.sol new file mode 100644 index 00000000..e6ca3364 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure returns (uint r) { + assembly { function f() -> x { x := 1 } r := f() } + } + function g() public pure returns (uint r) { + assembly { function f() -> x { x := 2 } r := f() } + } +} +// ---- +// f() -> 1 +// g() -> 2 diff --git a/examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash_standard_input.json b/examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash_standard_input.json new file mode 100644 index 00000000..0b34fe36 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_function_name_clash/function_name_clash_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call.sol new file mode 100644 index 00000000..c925823d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call.sol @@ -0,0 +1,24 @@ +contract C { + function f() public { + assembly { + let d:= 0x10 + + function asmfun(a, b, c) -> x, y, z { + x := g(a) + function g(r) -> s { + s := mul(r, r) + } + y := g(b) + z := 7 + } + let a1, b1, c1 := asmfun(1, 2, 3) + mstore(0x00, a1) + mstore(0x20, b1) + mstore(0x40, c1) + mstore(0x60, d) + return (0, 0x80) + } + } +} +// ---- +// f() -> 0x1, 0x4, 0x7, 0x10 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call_standard_input.json new file mode 100644 index 00000000..6c0bf1b0 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_embedded_function_call/inline_assembly_embedded_function_call_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for.sol new file mode 100644 index 00000000..848e9016 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for.sol @@ -0,0 +1,23 @@ +contract C { + function f(uint256 a) public returns (uint256 b) { + assembly { + function fac(n) -> nf { + nf := 1 + for { + let i := n + } gt(i, 0) { + i := sub(i, 1) + } { + nf := mul(nf, i) + } + } + b := fac(a) + } + } +} +// ---- +// f(uint256): 0 -> 1 +// f(uint256): 1 -> 1 +// f(uint256): 2 -> 2 +// f(uint256): 3 -> 6 +// f(uint256): 4 -> 24 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for_standard_input.json new file mode 100644 index 00000000..f5aa58b1 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_for/inline_assembly_for_standard_input.json @@ -0,0 +1,250 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "tstore_hidden_staticcall.sol": { + "content": "contract C {\n function f() internal {\n assembly {\n tstore(0, 0)\n }\n }\n function g() public view {\n function() internal ptr = f;\n function() internal view ptr2;\n assembly { ptr2 := ptr }\n ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n }\n function test() public {\n this.g(); // an external call to a view function should use static call\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n" + }, + "inline_assembly_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n function f() -> o1 {\n sstore(z.slot, 7)\n o1 := y.offset\n }\n off2 := f()\n }\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "inline_assembly_write_to_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r, bytes32 r2) {\n assembly {\n r := 7\n r2 := \"abcdef\"\n }\n }\n}\n// ----\n// f() -> 7, \"abcdef\"\n" + }, + "slot_access.sol": { + "content": "contract C {\n struct S {\n uint a;\n uint b;\n }\n\n mapping(uint => S) public mappingAccess;\n\n function data() internal view returns (S storage _data) {\n // We need to assign it from somewhere, otherwise we would\n // get an \"uninitialized access\" error.\n _data = mappingAccess[20];\n\n bytes32 slot = keccak256(abi.encode(uint(1), uint(0)));\n assembly {\n _data.slot := slot\n }\n }\n\n function set(uint x) public {\n data().a = x;\n }\n\n function get() public view returns (uint) {\n return data().a;\n }\n}\n// ----\n// get() -> 0\n// mappingAccess(uint256): 1 -> 0, 0\n// set(uint256): 4\n// get() -> 4\n// mappingAccess(uint256): 1 -> 4, 0\n" + }, + "optimize_memory_store_multi_block.sol": { + "content": "contract C {\n\tfunction f() external returns (uint256 x) {\n\t\tassembly {\n\t\t\tmstore(0, 0x42)\n\t\t}\n\t\tassembly {\n\t\t\tx := mload(0)\n\t\t}\n\t}\n\tfunction g() external returns (bool) {\n\t\tuint initialFreeMemoryPointer;\n\t\tassembly {\n\t\t\tinitialFreeMemoryPointer := mload(0x40)\n\t\t}\n\t\tassembly {\n\t\t\tlet ptr := mload(0x40)\n\t\t\tmstore(0x40, add(ptr, 0x20))\n\t\t}\n\t\tuint finalFreeMemoryPointer;\n\t\tassembly {\n\t\t\tfinalFreeMemoryPointer := mload(0x40)\n\t\t}\n\t\tassert(initialFreeMemoryPointer != finalFreeMemoryPointer);\n\t\treturn true;\n\t}\n}\n// ----\n// f() -> 0x42\n// g() -> true\n" + }, + "inline_assembly_for.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n nf := 1\n for {\n let i := n\n } gt(i, 0) {\n i := sub(i, 1)\n } {\n nf := mul(nf, i)\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2.sol new file mode 100644 index 00000000..2d817951 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2.sol @@ -0,0 +1,26 @@ +contract C { + uint256 st; + + function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) { + st = 0; + assembly { + function sideeffect(r) -> x { + sstore(0, add(sload(0), r)) + x := 1 + } + for { + let i := a + } eq(i, sideeffect(2)) { + d := add(d, 3) + } { + b := i + i := 0 + } + } + c = st; + } +} +// ---- +// f(uint256): 0 -> 0, 2, 0 +// f(uint256): 1 -> 1, 4, 3 +// f(uint256): 2 -> 0, 2, 0 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2_standard_input.json new file mode 100644 index 00000000..65576b64 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_for2/inline_assembly_for2_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call.sol new file mode 100644 index 00000000..de198dff --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call.sol @@ -0,0 +1,18 @@ +contract C { + function f() public { + assembly { + function asmfun(a, b, c) -> x, y, z { + x := a + y := b + z := 7 + } + let a1, b1, c1 := asmfun(1, 2, 3) + mstore(0x00, a1) + mstore(0x20, b1) + mstore(0x40, c1) + return (0, 0x60) + } + } +} +// ---- +// f() -> 1, 2, 7 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call_standard_input.json new file mode 100644 index 00000000..3ca6ccf2 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call/inline_assembly_function_call_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2.sol new file mode 100644 index 00000000..d21084aa --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2.sol @@ -0,0 +1,21 @@ +contract C { + function f() public { + assembly { + let d := 0x10 + + function asmfun(a, b, c) -> x, y, z { + x := a + y := b + z := 7 + } + let a1, b1, c1 := asmfun(1, 2, 3) + mstore(0x00, a1) + mstore(0x20, b1) + mstore(0x40, c1) + mstore(0x60, d) + return (0, 0x80) + } + } +} +// ---- +// f() -> 0x1, 0x2, 0x7, 0x10 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2_standard_input.json new file mode 100644 index 00000000..17d12321 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call2/inline_assembly_function_call2_standard_input.json @@ -0,0 +1,196 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment.sol new file mode 100644 index 00000000..e2e07823 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment.sol @@ -0,0 +1,20 @@ +contract C { + function f() public { + assembly { + let a1, b1, c1 + + function asmfun(a, b, c) -> x, y, z { + x := a + y := b + z := 7 + } + a1, b1, c1 := asmfun(1, 2, 3) + mstore(0x00, a1) + mstore(0x20, b1) + mstore(0x40, c1) + return (0, 0x60) + } + } +} +// ---- +// f() -> 1, 2, 7 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment_standard_input.json new file mode 100644 index 00000000..79b4be0d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_function_call_assignment/inline_assembly_function_call_assignment_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if.sol new file mode 100644 index 00000000..ebe50f51 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if.sol @@ -0,0 +1,14 @@ +contract C { + function f(uint256 a) public returns (uint256 b) { + assembly { + if gt(a, 1) { + b := 2 + } + } + } +} +// ---- +// f(uint256): 0 -> 0 +// f(uint256): 1 -> 0 +// f(uint256): 2 -> 2 +// f(uint256): 3 -> 2 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if_standard_input.json new file mode 100644 index 00000000..1f8936fe --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_if/inline_assembly_if_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers.sol new file mode 100644 index 00000000..e050d2b5 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers.sol @@ -0,0 +1,32 @@ +contract C { + modifier m { + uint256 a = 1; + assembly { + a := 2 + } + if (a != 2) revert(); + _; + } + + function f() public m returns (bool) { + return true; + } + + modifier n { + uint256 a = 1; + assembly { + a := 2 + } + if (a != 2) + _; + revert(); + } + + function g() public n returns (bool) { + // This statement should never execute. + return true; + } +} +// ---- +// f() -> true +// g() -> FAILURE diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers_standard_input.json new file mode 100644 index 00000000..17b27cf4 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_in_modifiers/inline_assembly_in_modifiers_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access.sol new file mode 100644 index 00000000..1f6a50d6 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access.sol @@ -0,0 +1,12 @@ +contract C { + function test() public returns (bytes memory) { + bytes memory x = new bytes(5); + for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1)); + assembly { + mstore(add(x, 32), "12345678901234567890123456789012") + } + return x; + } +} +// ---- +// test() -> 0x20, 0x5, "12345" diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access_standard_input.json new file mode 100644 index 00000000..0df7f932 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_memory_access/inline_assembly_memory_access_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack.sol new file mode 100644 index 00000000..ae4b94ed --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint256 r) { + for (uint256 x = 0; x < 10; ++x) + assembly { + r := add(r, x) + } + } +} +// ---- +// f() -> 45 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack_standard_input.json new file mode 100644 index 00000000..347a15c1 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_read_and_write_stack/inline_assembly_read_and_write_stack_standard_input.json @@ -0,0 +1,226 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion.sol new file mode 100644 index 00000000..a5095131 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion.sol @@ -0,0 +1,25 @@ +contract C { + function f(uint256 a) public returns (uint256 b) { + assembly { + function fac(n) -> nf { + switch n + case 0 { + nf := 1 + } + case 1 { + nf := 1 + } + default { + nf := mul(n, fac(sub(n, 1))) + } + } + b := fac(a) + } + } +} +// ---- +// f(uint256): 0 -> 1 +// f(uint256): 1 -> 1 +// f(uint256): 2 -> 2 +// f(uint256): 3 -> 6 +// f(uint256): 4 -> 24 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion_standard_input.json new file mode 100644 index 00000000..96652eab --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_recursion/inline_assembly_recursion_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access.sol new file mode 100644 index 00000000..254bc747 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access.sol @@ -0,0 +1,21 @@ +contract C { + uint16 x; + uint16 public y; + uint256 public z; + + function f() public returns (bool) { + uint256 off1; + uint256 off2; + assembly { + sstore(z.slot, 7) + off1 := z.offset + off2 := y.offset + } + assert(off1 == 0); + assert(off2 == 2); + return true; + } +} +// ---- +// f() -> true +// z() -> 7 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access_standard_input.json new file mode 100644 index 00000000..fe65dd53 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access/inline_assembly_storage_access_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function.sol new file mode 100644 index 00000000..80cd7e11 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function.sol @@ -0,0 +1,22 @@ +contract C { + uint16 x; + uint16 public y; + uint256 public z; + + function f() public returns (bool) { + uint256 off1; + uint256 off2; + assembly { + function f() -> o1 { + sstore(z.slot, 7) + o1 := y.offset + } + off2 := f() + } + assert(off2 == 2); + return true; + } +} +// ---- +// f() -> true +// z() -> 7 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function_standard_input.json new file mode 100644 index 00000000..b748fe9a --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_inside_function/inline_assembly_storage_access_inside_function_standard_input.json @@ -0,0 +1,238 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "tstore_hidden_staticcall.sol": { + "content": "contract C {\n function f() internal {\n assembly {\n tstore(0, 0)\n }\n }\n function g() public view {\n function() internal ptr = f;\n function() internal view ptr2;\n assembly { ptr2 := ptr }\n ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n }\n function test() public {\n this.g(); // an external call to a view function should use static call\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n" + }, + "inline_assembly_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n function f() -> o1 {\n sstore(z.slot, 7)\n o1 := y.offset\n }\n off2 := f()\n }\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var.sol new file mode 100644 index 00000000..c7728068 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var.sol @@ -0,0 +1,16 @@ +contract C { + uint256[] public a; + + function f() public returns (uint256) { + uint256[] storage x = a; + uint256 off; + assembly { + sstore(x.slot, 7) + off := x.offset + } + assert(off == 0); + return a.length; + } +} +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var_standard_input.json new file mode 100644 index 00000000..6f91ac22 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_local_var/inline_assembly_storage_access_local_var_standard_input.json @@ -0,0 +1,223 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer.sol new file mode 100644 index 00000000..6c382ef9 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer.sol @@ -0,0 +1,24 @@ +contract C { + struct Data { + uint256 contents; + } + uint256 public separator; + Data public a; + uint256 public separator2; + + function f() public returns (bool) { + Data storage x = a; + uint256 off; + assembly { + sstore(x.slot, 7) + off := x.offset + } + assert(off == 0); + return true; + } +} +// ---- +// f() -> true +// a() -> 7 +// separator() -> 0 +// separator2() -> 0 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer_standard_input.json new file mode 100644 index 00000000..8dd26973 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_storage_access_via_pointer/inline_assembly_storage_access_via_pointer_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch.sol new file mode 100644 index 00000000..615d6959 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch.sol @@ -0,0 +1,21 @@ +contract C { + function f(uint256 a) public returns (uint256 b) { + assembly { + switch a + case 1 { + b := 8 + } + case 2 { + b := 9 + } + default { + b := 2 + } + } + } +} +// ---- +// f(uint256): 0 -> 2 +// f(uint256): 1 -> 8 +// f(uint256): 2 -> 9 +// f(uint256): 3 -> 2 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch_standard_input.json new file mode 100644 index 00000000..9361c463 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_switch/inline_assembly_switch_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function.sol new file mode 100644 index 00000000..489f1a4c --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function.sol @@ -0,0 +1,22 @@ +contract C { + uint16 transient x; + uint16 public transient y; + uint256 public transient z; + + function f() public returns (uint256) { + uint256 offset; + assembly { + function f() -> o1 { + tstore(z.slot, 7) + o1 := y.offset + } + offset := f() + } + assert(offset == 2); + return z; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function_standard_input.json new file mode 100644 index 00000000..d9fee623 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_transient_storage_access_inside_function/inline_assembly_transient_storage_access_inside_function_standard_input.json @@ -0,0 +1,205 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack.sol b/examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack.sol new file mode 100644 index 00000000..ed20bfe2 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint256 r, bytes32 r2) { + assembly { + r := 7 + r2 := "abcdef" + } + } +} +// ---- +// f() -> 7, "abcdef" diff --git a/examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack_standard_input.json b/examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack_standard_input.json new file mode 100644 index 00000000..15d428cb --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inline_assembly_write_to_stack/inline_assembly_write_to_stack_standard_input.json @@ -0,0 +1,241 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "tstore_hidden_staticcall.sol": { + "content": "contract C {\n function f() internal {\n assembly {\n tstore(0, 0)\n }\n }\n function g() public view {\n function() internal ptr = f;\n function() internal view ptr2;\n assembly { ptr2 := ptr }\n ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n }\n function test() public {\n this.g(); // an external call to a view function should use static call\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n" + }, + "inline_assembly_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n function f() -> o1 {\n sstore(z.slot, 7)\n o1 := y.offset\n }\n off2 := f()\n }\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "inline_assembly_write_to_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r, bytes32 r2) {\n assembly {\n r := 7\n r2 := \"abcdef\"\n }\n }\n}\n// ----\n// f() -> 7, \"abcdef\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let.sol b/examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let.sol new file mode 100644 index 00000000..17e14e8a --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let.sol @@ -0,0 +1,12 @@ +contract C { + function f() public pure returns (uint a, uint b) { + assembly { + let x + let y, z + a := x + b := z + } + } +} +// ---- +// f() -> 0, 0 diff --git a/examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let_standard_input.json b/examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let_standard_input.json new file mode 100644 index 00000000..3123033e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_inlineasm_empty_let/inlineasm_empty_let_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly.sol b/examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly.sol new file mode 100644 index 00000000..253af989 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (bytes32 ret) { + assembly { + ret := keccak256(0, 0) + } + } +} +// ---- +// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly_standard_input.json b/examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly_standard_input.json new file mode 100644 index 00000000..9eba7b6e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_assembly/keccak256_assembly_standard_input.json @@ -0,0 +1,193 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization.sol b/examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization.sol new file mode 100644 index 00000000..2a245b35 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization.sol @@ -0,0 +1,14 @@ +contract C { + function f() public view returns (bool ret) { + assembly { + let x := calldataload(0) + mstore(0, x) + mstore(0x20, x) + let a := keccak256(0, 4) + let b := keccak256(0x20, 4) + ret := eq(a, b) + } + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization_standard_input.json b/examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization_standard_input.json new file mode 100644 index 00000000..34cab61e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_optimization/keccak256_optimization_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location.sol b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location.sol new file mode 100644 index 00000000..233e4f72 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location.sol @@ -0,0 +1,14 @@ +contract C { + function f() public view returns (bool ret) { + assembly { + let x := calldataload(0) + mstore(0, x) + mstore(0x20, x) + let a := keccak256(0, 4) + let b := keccak256(0x20, 8) + ret := eq(a, b) + } + } +} +// ---- +// f() -> false diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location_standard_input.json b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location_standard_input.json new file mode 100644 index 00000000..3fab149d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_bug_different_memory_location/keccak256_optimizer_bug_different_memory_location_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug.sol b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug.sol new file mode 100644 index 00000000..4023a809 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug.sol @@ -0,0 +1,19 @@ +contract C { + uint[] data; + + function val() public returns (bool) { + assembly { + sstore(0, 2) + mstore(0, 0) + sstore(keccak256(0, 32), 234) + // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as + // keccak256(0, 32), leading to `data[1] == 123` being true. + sstore(add(keccak256(0, 23), 1), 123) + } + assert(data[1] != 123); + assert(data[1] == 0); + return true; + } +} +// ---- +// val() -> true diff --git a/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug_standard_input.json b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug_standard_input.json new file mode 100644 index 00000000..ac01a31d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak256_optimizer_cache_bug/keccak256_optimizer_cache_bug_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string.sol b/examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string.sol new file mode 100644 index 00000000..35f8ae5e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string.sol @@ -0,0 +1,13 @@ +contract C { + function f(string memory s) public returns (bool ret) { + assembly { + let a := keccak256(s, 32) + let b := keccak256(s, 8) + ret := eq(a, b) + } + } +} +// ---- +// f(string): "" -> false +// f(string): 0x20, 5, "hello" -> false +// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false diff --git a/examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string_standard_input.json b/examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string_standard_input.json new file mode 100644 index 00000000..7aa46a2d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak_optimization_bug_string/keccak_optimization_bug_string_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization.sol b/examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization.sol new file mode 100644 index 00000000..88088bbd --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization.sol @@ -0,0 +1,33 @@ +contract C { + function g() public returns (uint ret) { + uint x = type(uint).max; + assembly { + mstore(0x20, x) + // both old and new optimizer should be able to evaluate this + ret := keccak256(0x20, 16) + } + } + + function f() public returns (uint ret) { + uint x = type(uint).max; + assembly { + mstore(0x20, x) + // For Yul optimizer, load resolver and loop invariant code motion + // would take the Keccak-256 outside the loop. For the old-optimizer, + // this is not possible. + // Net savings approximately: 20 * cost of Keccak-256 = 572 + for {let i := 0} lt(i, 20) { i := add(i, 1) } { + ret := keccak256(0x20, 16) + } + } + } +} +// ---- +// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 +// gas irOptimized: 22239 +// gas legacy: 23385 +// gas legacyOptimized: 23092 +// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 +// gas irOptimized: 21277 +// gas legacy: 21462 +// gas legacyOptimized: 21256 diff --git a/examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization_standard_input.json b/examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization_standard_input.json new file mode 100644 index 00000000..f22d49e1 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_keccak_yul_optimization/keccak_yul_optimization_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_leave/leave.sol b/examples/test/semanticTests/inlineAssembly_leave/leave.sol new file mode 100644 index 00000000..40add273 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_leave/leave.sol @@ -0,0 +1,14 @@ +contract C { + function f() public pure returns (uint w) { + assembly { + function f() -> t { + t := 2 + leave + t := 9 + } + w := f() + } + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/inlineAssembly_leave/leave_standard_input.json b/examples/test/semanticTests/inlineAssembly_leave/leave_standard_input.json new file mode 100644 index 00000000..3964295c --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_leave/leave_standard_input.json @@ -0,0 +1,214 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_mcopy/mcopy.sol b/examples/test/semanticTests/inlineAssembly_mcopy/mcopy.sol new file mode 100644 index 00000000..e98409f3 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy/mcopy.sol @@ -0,0 +1,14 @@ +contract C { + function f(bytes memory src) public pure returns (bytes memory dst) { + assembly { + mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst + mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst + mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst + mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000 diff --git a/examples/test/semanticTests/inlineAssembly_mcopy/mcopy_standard_input.json b/examples/test/semanticTests/inlineAssembly_mcopy/mcopy_standard_input.json new file mode 100644 index 00000000..646730ef --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy/mcopy_standard_input.json @@ -0,0 +1,208 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun.sol b/examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun.sol new file mode 100644 index 00000000..4f50d1dd --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun.sol @@ -0,0 +1,22 @@ +contract C { + function f() public pure returns (uint result) { + assembly { + let mcopy := 1 + result := mcopy + } + } + + function g() public pure returns (uint result) { + assembly { + function mcopy() -> r { + r := 1000 + } + result := mcopy() + } + } +} +// ==== +// EVMVersion: 1 +// g() -> 1000 diff --git a/examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun_standard_input.json b/examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun_standard_input.json new file mode 100644 index 00000000..71be5719 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy_as_identifier_pre_cancun/mcopy_as_identifier_pre_cancun_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty.sol b/examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty.sol new file mode 100644 index 00000000..e34e443b --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty.sol @@ -0,0 +1,18 @@ +contract C { + function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) { + out = pattern; + + // This should have no effect on output + assembly { + mcopy(add(out, 0x20), add(out, 0x30), 0) + mcopy(add(out, 0x30), add(out, 0x30), 0) + mcopy(add(out, 0x40), add(out, 0x30), 0) + + mcopy(add(out, 0x21), 0, 0) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff diff --git a/examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty_standard_input.json b/examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty_standard_input.json new file mode 100644 index 00000000..950e6858 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy_empty/mcopy_empty_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap.sol b/examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap.sol new file mode 100644 index 00000000..95f517da --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap.sol @@ -0,0 +1,39 @@ +function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) { + out = + hex"2222222222222222333333333333333344444444444444445555555555555555" + hex"6666666666666666777777777777777788888888888888889999999999999999" + hex"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd"; + assembly { + mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length) + } +} + +contract C { + function mcopy_to_right_overlap() public pure returns (bytes memory) { + return copy(0x20, 0x10, 0x30); + } + + function mcopy_to_left_overlap() public pure returns (bytes memory) { + return copy(0x10, 0x20, 0x30); + } + + function mcopy_in_place() public pure returns (bytes memory) { + return copy(0x10, 0x10, 0x40); + } + + function mcopy_to_right_no_overlap() public pure returns (bytes memory) { + return copy(0x30, 0x10, 0x20); + } + + function mcopy_to_left_no_overlap() public pure returns (bytes memory) { + return copy(0x10, 0x30, 0x20); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd +// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd +// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd +// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd +// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd diff --git a/examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap_standard_input.json b/examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap_standard_input.json new file mode 100644 index 00000000..2cace2e4 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_mcopy_overlap/mcopy_overlap_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block.sol b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block.sol new file mode 100644 index 00000000..1a72925d --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block.sol @@ -0,0 +1,29 @@ +contract C { + function f() external returns (uint256 x) { + assembly { + mstore(0, 0x42) + } + assembly { + x := mload(0) + } + } + function g() external returns (bool) { + uint initialFreeMemoryPointer; + assembly { + initialFreeMemoryPointer := mload(0x40) + } + assembly { + let ptr := mload(0x40) + mstore(0x40, add(ptr, 0x20)) + } + uint finalFreeMemoryPointer; + assembly { + finalFreeMemoryPointer := mload(0x40) + } + assert(initialFreeMemoryPointer != finalFreeMemoryPointer); + return true; + } +} +// ---- +// f() -> 0x42 +// g() -> true diff --git a/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block_standard_input.json b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block_standard_input.json new file mode 100644 index 00000000..c20342a8 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block/optimize_memory_store_multi_block_standard_input.json @@ -0,0 +1,247 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "tstore_hidden_staticcall.sol": { + "content": "contract C {\n function f() internal {\n assembly {\n tstore(0, 0)\n }\n }\n function g() public view {\n function() internal ptr = f;\n function() internal view ptr2;\n assembly { ptr2 := ptr }\n ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n }\n function test() public {\n this.g(); // an external call to a view function should use static call\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n" + }, + "inline_assembly_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n function f() -> o1 {\n sstore(z.slot, 7)\n o1 := y.offset\n }\n off2 := f()\n }\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "inline_assembly_write_to_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r, bytes32 r2) {\n assembly {\n r := 7\n r2 := \"abcdef\"\n }\n }\n}\n// ----\n// f() -> 7, \"abcdef\"\n" + }, + "slot_access.sol": { + "content": "contract C {\n struct S {\n uint a;\n uint b;\n }\n\n mapping(uint => S) public mappingAccess;\n\n function data() internal view returns (S storage _data) {\n // We need to assign it from somewhere, otherwise we would\n // get an \"uninitialized access\" error.\n _data = mappingAccess[20];\n\n bytes32 slot = keccak256(abi.encode(uint(1), uint(0)));\n assembly {\n _data.slot := slot\n }\n }\n\n function set(uint x) public {\n data().a = x;\n }\n\n function get() public view returns (uint) {\n return data().a;\n }\n}\n// ----\n// get() -> 0\n// mappingAccess(uint256): 1 -> 0, 0\n// set(uint256): 4\n// get() -> 4\n// mappingAccess(uint256): 1 -> 4, 0\n" + }, + "optimize_memory_store_multi_block.sol": { + "content": "contract C {\n\tfunction f() external returns (uint256 x) {\n\t\tassembly {\n\t\t\tmstore(0, 0x42)\n\t\t}\n\t\tassembly {\n\t\t\tx := mload(0)\n\t\t}\n\t}\n\tfunction g() external returns (bool) {\n\t\tuint initialFreeMemoryPointer;\n\t\tassembly {\n\t\t\tinitialFreeMemoryPointer := mload(0x40)\n\t\t}\n\t\tassembly {\n\t\t\tlet ptr := mload(0x40)\n\t\t\tmstore(0x40, add(ptr, 0x20))\n\t\t}\n\t\tuint finalFreeMemoryPointer;\n\t\tassembly {\n\t\t\tfinalFreeMemoryPointer := mload(0x40)\n\t\t}\n\t\tassert(initialFreeMemoryPointer != finalFreeMemoryPointer);\n\t\treturn true;\n\t}\n}\n// ----\n// f() -> 0x42\n// g() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport.sol b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport.sol new file mode 100644 index 00000000..023d178a --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport.sol @@ -0,0 +1,23 @@ +contract Test { + uint256 x; + + function test() public returns (uint256) { + uint256 a = myGetX(); + x = 5; + uint256 b = myGetX(); + assembly { + log0(0, 64) + } + return a + b + myGetX(); + } + + function myGetX() internal view returns (uint256) { + assembly { + mstore(1, 0x123456789abcdef) + } + return x; + } +} +// ---- +// test() -> 10 +// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport_standard_input.json b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport_standard_input.json new file mode 100644 index 00000000..19bd2b88 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_optimize_memory_store_multi_block_bugreport/optimize_memory_store_multi_block_bugreport_standard_input.json @@ -0,0 +1,202 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao.sol b/examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao.sol new file mode 100644 index 00000000..8a71c8f4 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao.sol @@ -0,0 +1,11 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + ret := prevrandao() + } + } +} +// ==== +// EVMVersion: >=paris +// ---- +// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777 diff --git a/examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao_standard_input.json b/examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao_standard_input.json new file mode 100644 index 00000000..966de087 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_prevrandao/prevrandao_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance.sol b/examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance.sol new file mode 100644 index 00000000..1637de5b --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance.sol @@ -0,0 +1,11 @@ +contract C { + function f() public payable returns (uint ret) { + assembly { + ret := selfbalance() + } + } +} +// ==== +// EVMVersion: >=istanbul +// ---- +// f(), 254 wei -> 254 diff --git a/examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance_standard_input.json b/examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance_standard_input.json new file mode 100644 index 00000000..67cab31b --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_selfbalance/selfbalance_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode.sol b/examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode.sol new file mode 100644 index 00000000..d7e585e3 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode.sol @@ -0,0 +1,11 @@ +contract C { + function add(uint, uint) public pure returns (uint) { return 7; } + function g() public pure returns (uint x, uint y) { + x = add(1, 2); + assembly { + y := add(1, 2) + } + } +} +// ---- +// g() -> 7, 3 diff --git a/examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode_standard_input.json b/examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode_standard_input.json new file mode 100644 index 00000000..080e897b --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_shadowing_local_function_opcode/shadowing_local_function_opcode_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_slot_access/slot_access.sol b/examples/test/semanticTests/inlineAssembly_slot_access/slot_access.sol new file mode 100644 index 00000000..abfc6d09 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_slot_access/slot_access.sol @@ -0,0 +1,33 @@ +contract C { + struct S { + uint a; + uint b; + } + + mapping(uint => S) public mappingAccess; + + function data() internal view returns (S storage _data) { + // We need to assign it from somewhere, otherwise we would + // get an "uninitialized access" error. + _data = mappingAccess[20]; + + bytes32 slot = keccak256(abi.encode(uint(1), uint(0))); + assembly { + _data.slot := slot + } + } + + function set(uint x) public { + data().a = x; + } + + function get() public view returns (uint) { + return data().a; + } +} +// ---- +// get() -> 0 +// mappingAccess(uint256): 1 -> 0, 0 +// set(uint256): 4 +// get() -> 4 +// mappingAccess(uint256): 1 -> 4, 0 diff --git a/examples/test/semanticTests/inlineAssembly_slot_access/slot_access_standard_input.json b/examples/test/semanticTests/inlineAssembly_slot_access/slot_access_standard_input.json new file mode 100644 index 00000000..48febd36 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_slot_access/slot_access_standard_input.json @@ -0,0 +1,244 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "tstore_hidden_staticcall.sol": { + "content": "contract C {\n function f() internal {\n assembly {\n tstore(0, 0)\n }\n }\n function g() public view {\n function() internal ptr = f;\n function() internal view ptr2;\n assembly { ptr2 := ptr }\n ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n }\n function test() public {\n this.g(); // an external call to a view function should use static call\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n" + }, + "inline_assembly_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n function f() -> o1 {\n sstore(z.slot, 7)\n o1 := y.offset\n }\n off2 := f()\n }\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "inline_assembly_write_to_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r, bytes32 r2) {\n assembly {\n r := 7\n r2 := \"abcdef\"\n }\n }\n}\n// ----\n// f() -> 7, \"abcdef\"\n" + }, + "slot_access.sol": { + "content": "contract C {\n struct S {\n uint a;\n uint b;\n }\n\n mapping(uint => S) public mappingAccess;\n\n function data() internal view returns (S storage _data) {\n // We need to assign it from somewhere, otherwise we would\n // get an \"uninitialized access\" error.\n _data = mappingAccess[20];\n\n bytes32 slot = keccak256(abi.encode(uint(1), uint(0)));\n assembly {\n _data.slot := slot\n }\n }\n\n function set(uint x) public {\n data().a = x;\n }\n\n function get() public view returns (uint) {\n return data().a;\n }\n}\n// ----\n// get() -> 0\n// mappingAccess(uint256): 1 -> 0, 0\n// set(uint256): 4\n// get() -> 4\n// mappingAccess(uint256): 1 -> 4, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer.sol b/examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer.sol new file mode 100644 index 00000000..e080985e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer.sol @@ -0,0 +1,31 @@ +contract C { + mapping(uint => uint) private m0; + mapping(uint => uint) private m1; + mapping(uint => uint) private m2; + + function f(uint i) public returns (uint slot, uint offset) { + mapping(uint => uint) storage m0Ptr = m0; + mapping(uint => uint) storage m1Ptr = m1; + mapping(uint => uint) storage m2Ptr = m2; + + assembly { + switch i + case 1 { + slot := m1Ptr.slot + offset := m1Ptr.offset + } + case 2 { + slot := m2Ptr.slot + offset := m2Ptr.offset + } + default { + slot := m0Ptr.slot + offset := m0Ptr.offset + } + } + } +} +// ---- +// f(uint256): 0 -> 0, 0 +// f(uint256): 1 -> 1, 0 +// f(uint256): 2 -> 2, 0 diff --git a/examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer_standard_input.json b/examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer_standard_input.json new file mode 100644 index 00000000..241c8f5e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_slot_access_via_mapping_pointer/slot_access_via_mapping_pointer_standard_input.json @@ -0,0 +1,220 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun.sol b/examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun.sol new file mode 100644 index 00000000..930c531e --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun.sol @@ -0,0 +1,25 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let tload := sload(0) + let tstore := add(tload, 1) + ret := tstore + } + } + function g() public view returns (uint ret) { + assembly { + function tstore() -> a { + a := 2 + } + function tload() -> b { + b := 3 + } + ret := add(tstore(), tload()) + } + } +} +// ==== +// EVMVersion: 1 +// g() -> 5 diff --git a/examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun_standard_input.json b/examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun_standard_input.json new file mode 100644 index 00000000..16a23d18 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_tload_tstore_not_reserved_before_cancun/tload_tstore_not_reserved_before_cancun_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation.sol new file mode 100644 index 00000000..5a97dc84 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation.sol @@ -0,0 +1,14 @@ +contract C { + constructor() { + uint x; + assembly { + tstore(0, 42) + x := tload(0) + } + assert(x == 42); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// constructor() -> diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation_standard_input.json new file mode 100644 index 00000000..443c89d2 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_creation/transient_storage_creation_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls.sol new file mode 100644 index 00000000..e43fc475 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls.sol @@ -0,0 +1,76 @@ +contract D { + function addOne() external { + assembly { + let x := tload(0) + tstore(0, add(x, 1)) + } + } + function get() external returns (uint x) { + assembly { + x := tload(0) + } + } +} + +contract C { + function set(uint x) external { + assembly { + tstore(0, x) + } + } + + function get() external view returns (uint x) { + assembly { + x := tload(0) + } + } + + function testDelegateCall() external returns (bool) { + this.set(5); + D d = new D(); + // Caller contract is the owner of the transient storage + (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ())); + require(success); + require(this.get() == 6); + return true; + } + + function testCall() external returns (bool) { + this.set(5); + D d = new D(); + // Callee/Target contract is the owner of the transient storage + (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ())); + require(success); + require(d.get() == 1); + return true; + } + + function tloadAllowedStaticCall() external returns (bool) { + this.set(5); + D d = new D(); + (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ())); + require(success); + require(abi.decode(result, (uint)) == 0); + return true; + } + + function tstoreNotAllowedStaticCall() external returns (bool) { + D d = new D(); + (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ())); + require(!success); + return true; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// testDelegateCall() -> true +// testCall() -> true +// tloadAllowedStaticCall() -> true +// tstoreNotAllowedStaticCall() -> true +// gas irOptimized: 98419720 +// gas irOptimized code: 19000 +// gas legacy: 98409086 +// gas legacy code: 30000 +// gas legacyOptimized: 98420962 +// gas legacyOptimized code: 17800 diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls_standard_input.json new file mode 100644 index 00000000..5d30e326 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_low_level_calls/transient_storage_low_level_calls_standard_input.json @@ -0,0 +1,190 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions.sol new file mode 100644 index 00000000..c8228655 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions.sol @@ -0,0 +1,24 @@ +contract C { + function get(uint256 addr) external view returns (uint256 x) { + assembly { + x := tload(addr) + } + } + function set(uint256 addr, uint256 x) external { + assembly { + tstore(addr, x) + } + } + function test() public { + assert(this.get(0) == 0 && this.get(42) == 0); + this.set(0, 21); + assert(this.get(0) == 21 && this.get(42) == 0); + this.set(42, 131); + assert(this.get(0) == 21 && this.get(42) == 131); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// test() -> +// test() -> diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions_standard_input.json new file mode 100644 index 00000000..ffdae316 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_calls_different_transactions/transient_storage_multiple_calls_different_transactions_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions.sol new file mode 100644 index 00000000..931f34de --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions.sol @@ -0,0 +1,38 @@ +contract C { + function set(uint value) private { + assembly { + tstore(0, value) + } + } + + function get() private view returns (uint value) { + assembly { + value := tload(0) + } + } + + function f() external { + assembly { + tstore(0, 42) + } + } + + function g() external view returns(uint r) { + assembly { + r := tload(0) + } + } + + function h() external returns (uint x) { + set(99); + x = get(); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// g() -> 0 +// f() -> +// g() -> 0 +// h() -> 0x63 +// g() -> 0 diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions_standard_input.json new file mode 100644 index 00000000..d84b9241 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_multiple_transactions/transient_storage_multiple_transactions_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime.sol new file mode 100644 index 00000000..e41fcb60 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime.sol @@ -0,0 +1,24 @@ +contract C { + constructor() { + uint x; + assembly { + tstore(0, 42) + x := tload(0) + } + assert(x == 42); + } + + function f() public returns (uint x) { + assembly { + x := tload(0) + if eq(x, 42) { + revert(0, 0) + } + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// constructor() -> +// f() -> 0 diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime_standard_input.json new file mode 100644 index 00000000..33a0ea03 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_reset_between_creation_runtime/transient_storage_reset_between_creation_runtime_standard_input.json @@ -0,0 +1,217 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks.sol new file mode 100644 index 00000000..101c3c10 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks.sol @@ -0,0 +1,24 @@ +contract C { + function f() external { + assembly { + tstore(0, 21) + mstore(0, 42) + sstore(0, 42) + if iszero(eq(tload(0), 21)) { + revert(0, 0) + } + } + } + function g() external view returns (uint s, uint m, uint t) { + assembly { + s := sload(0) + m := mload(0) + t := tload(0) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> +// g() -> 0x2a, 0, 0 diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks_standard_input.json new file mode 100644 index 00000000..6dbec772 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_sanity_checks/transient_storage_sanity_checks_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct.sol new file mode 100644 index 00000000..c2066ef8 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct.sol @@ -0,0 +1,54 @@ +contract C { + function set(uint value) external { + assembly { + tstore(0, value) + } + } + + function get() external view returns (uint value) { + assembly { + value := tload(0) + } + } + + function terminate(address payable a) external { + selfdestruct(a); + } +} + +contract D { + C public c; + + constructor() { + c = new C(); + } + + function destroy() external { + c.set(42); + c.terminate(payable(address(this))); + assert(c.get() == 42); + } + + function createAndDestroy() external { + c = new C(); + c.set(42); + c.terminate(payable(address(this))); + assert(c.get() == 42); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// constructor() -> +// gas irOptimized: 127596 +// gas irOptimized code: 221000 +// gas legacy: 149480 +// gas legacy code: 501200 +// gas legacyOptimized: 125846 +// gas legacyOptimized code: 203400 +// destroy() -> +// createAndDestroy() -> +// gas legacy: 67048 +// gas legacy code: 92600 +// gas legacyOptimized: 65677 +// gas legacyOptimized code: 39400 diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct_standard_input.json new file mode 100644 index 00000000..33a5ee2f --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_selfdestruct/transient_storage_selfdestruct_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock.sol b/examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock.sol new file mode 100644 index 00000000..0d05c926 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock.sol @@ -0,0 +1,22 @@ +contract C { + modifier nonreentrant { + assembly { + if tload(0) { revert(0, 0) } + tstore(0, 1) + } + _; + assembly { + tstore(0, 0) + } + } + function f(bool simulateReentrancy) nonreentrant public { + if (simulateReentrancy) { + f(false); + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f(bool): false -> +// f(bool): true -> FAILURE diff --git a/examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock_standard_input.json b/examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock_standard_input.json new file mode 100644 index 00000000..2c362535 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_transient_storage_simple_reentrancy_lock/transient_storage_simple_reentrancy_lock_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_truefalse/truefalse.sol b/examples/test/semanticTests/inlineAssembly_truefalse/truefalse.sol new file mode 100644 index 00000000..4183642b --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_truefalse/truefalse.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint x, uint y) { + assembly { + x := true + y := false + } + } +} +// ---- +// f() -> 1, 0 diff --git a/examples/test/semanticTests/inlineAssembly_truefalse/truefalse_standard_input.json b/examples/test/semanticTests/inlineAssembly_truefalse/truefalse_standard_input.json new file mode 100644 index 00000000..e75ade05 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_truefalse/truefalse_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall.sol b/examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall.sol new file mode 100644 index 00000000..4e4f30a7 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall.sol @@ -0,0 +1,23 @@ +contract C { + function f() internal { + assembly { + tstore(0, 0) + } + } + function g() public view { + function() internal ptr = f; + function() internal view ptr2; + assembly { ptr2 := ptr } + ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall + } + function test() public { + this.g(); // an external call to a view function should use static call + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// test() -> FAILURE +// gas irOptimized: 98437877 +// gas legacy: 98437871 +// gas legacyOptimized: 98437872 diff --git a/examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall_standard_input.json b/examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall_standard_input.json new file mode 100644 index 00000000..03590080 --- /dev/null +++ b/examples/test/semanticTests/inlineAssembly_tstore_hidden_staticcall/tstore_hidden_staticcall_standard_input.json @@ -0,0 +1,235 @@ +{ + "language": "Solidity", + "sources": { + "selfbalance.sol": { + "content": "contract C {\n function f() public payable returns (uint ret) {\n assembly {\n ret := selfbalance()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f(), 254 wei -> 254\n" + }, + "calldata_array_read.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint o, uint l, uint s) {\n assembly { l := x.length o := x.offset }\n uint[2] calldata t = x[1];\n // statically-sized arrays only use one slot, so we read directly.\n assembly { s := t }\n }\n}\n// ----\n// f(uint256[2][]): 0x20, 2, 1, 2, 3, 4 -> 0x44, 2, 0x84\n" + }, + "inline_assembly_storage_access_via_pointer.sol": { + "content": "contract C {\n struct Data {\n uint256 contents;\n }\n uint256 public separator;\n Data public a;\n uint256 public separator2;\n\n function f() public returns (bool) {\n Data storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return true;\n }\n}\n// ----\n// f() -> true\n// a() -> 7\n// separator() -> 0\n// separator2() -> 0\n" + }, + "calldata_struct_assign_and_return.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S { int8 x; int8 y; }\n function f() internal pure returns(S calldata s) {\n assembly {\n s := 0x24\n }\n }\n function g() public pure returns(int8, int8) {\n S calldata s = f();\n return (s.x, s.y);\n }\n function h() public pure returns(uint256) { f(); return 0x42; }\n function i() public pure returns(uint256) { abi.decode(msg.data[4:], (S)); return 0x42; }\n}\n// ----\n// g(): 0xCAFFEE, 0x42, 0x21 -> 0x42, 0x21\n// g(): 0xCAFFEE, 0x4242, 0x2121 -> FAILURE\n// g(): 0xCAFFEE, 0x42 -> 0x42, 0\n// h() -> 0x42\n// i() -> FAILURE\n" + }, + "inline_assembly_function_call_assignment.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let a1, b1, c1\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "external_function_pointer_address_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(address newAddress) view public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.address := newAddress\n\t\t}\n\n\t\treturn fp.address;\n\t}\n}\n// ----\n// testYul(address): 0x1234567890 -> 0x1234567890\n// testYul(address): 0xC0FFEE3EA7 -> 0xC0FFEE3EA7\n" + }, + "keccak_optimization_bug_string.sol": { + "content": "contract C {\n function f(string memory s) public returns (bool ret) {\n assembly {\n let a := keccak256(s, 32)\n let b := keccak256(s, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f(string): \"\" -> false\n// f(string): 0x20, 5, \"hello\" -> false\n// f(string): 0x20, 0x2e, 29457663690442756349866640336617293820574110049925353194191585327958485180523, 45859201465615193776739262511799714667061496775486067316261261194408342061056 -> false\n" + }, + "inlineasm_empty_let.sol": { + "content": "contract C {\n\tfunction f() public pure returns (uint a, uint b) {\n\t\tassembly {\n\t\t\tlet x\n\t\t\tlet y, z\n\t\t\ta := x\n\t\t\tb := z\n\t\t}\n\t}\n}\n// ----\n// f() -> 0, 0\n" + }, + "calldata_array_assign_dynamic.sol": { + "content": "contract C {\n function f(uint[2][] calldata x) public returns (uint[2][] memory r) {\n assembly { x.offset := 0x44 x.length := 2 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][]): 0x0, 1, 8, 7, 6, 5 -> 0x20, 2, 8, 7, 6, 5\n" + }, + "external_function_pointer_address.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (address adr) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tadr := fp.address\n\t\t}\n\t}\n\tfunction testSol() public returns (address) {\n\t\treturn this.testFunction.address;\n\t}\n}\n// ----\n// testYul() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testSol() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n" + }, + "inline_assembly_memory_access.sol": { + "content": "contract C {\n function test() public returns (bytes memory) {\n bytes memory x = new bytes(5);\n for (uint256 i = 0; i < x.length; ++i) x[i] = bytes1(uint8(i + 1));\n assembly {\n mstore(add(x, 32), \"12345678901234567890123456789012\")\n }\n return x;\n }\n}\n// ----\n// test() -> 0x20, 0x5, \"12345\"\n" + }, + "keccak256_optimizer_cache_bug.sol": { + "content": "contract C {\n uint[] data;\n\n function val() public returns (bool) {\n assembly {\n sstore(0, 2)\n mstore(0, 0)\n sstore(keccak256(0, 32), 234)\n // A bug in the caching mechanism previously caused keccak256(0, 23) to be the same as\n // keccak256(0, 32), leading to `data[1] == 123` being true.\n sstore(add(keccak256(0, 23), 1), 123)\n }\n assert(data[1] != 123);\n assert(data[1] == 0);\n return true;\n }\n}\n// ----\n// val() -> true\n" + }, + "mcopy_empty.sol": { + "content": "contract C {\n function mcopy_zero(bytes memory pattern) public pure returns (bytes memory out) {\n out = pattern;\n\n // This should have no effect on output\n assembly {\n mcopy(add(out, 0x20), add(out, 0x30), 0)\n mcopy(add(out, 0x30), add(out, 0x30), 0)\n mcopy(add(out, 0x40), add(out, 0x30), 0)\n\n mcopy(add(out, 0x21), 0, 0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_zero(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff\n" + }, + "keccak256_optimization.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 4)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> true\n" + }, + "keccak_yul_optimization.sol": { + "content": "contract C {\n function g() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // both old and new optimizer should be able to evaluate this\n ret := keccak256(0x20, 16)\n }\n }\n\n function f() public returns (uint ret) {\n uint x = type(uint).max;\n assembly {\n mstore(0x20, x)\n // For Yul optimizer, load resolver and loop invariant code motion\n // would take the Keccak-256 outside the loop. For the old-optimizer,\n // this is not possible.\n // Net savings approximately: 20 * cost of Keccak-256 = 572\n for {let i := 0} lt(i, 20) { i := add(i, 1) } {\n ret := keccak256(0x20, 16)\n }\n }\n }\n}\n// ----\n// f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 22239\n// gas legacy: 23385\n// gas legacyOptimized: 23092\n// g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80\n// gas irOptimized: 21277\n// gas legacy: 21462\n// gas legacyOptimized: 21256\n" + }, + "inline_assembly_if.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n if gt(a, 1) {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0\n// f(uint256): 1 -> 0\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 2\n" + }, + "tload_tstore_not_reserved_before_cancun.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let tload := sload(0)\n let tstore := add(tload, 1)\n ret := tstore\n }\n }\n function g() public view returns (uint ret) {\n assembly {\n function tstore() -> a {\n a := 2\n }\n function tload() -> b {\n b := 3\n }\n ret := add(tstore(), tload())\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 5\n" + }, + "transient_storage_sanity_checks.sol": { + "content": "contract C {\n function f() external {\n assembly {\n tstore(0, 21)\n mstore(0, 42)\n sstore(0, 42)\n if iszero(eq(tload(0), 21)) {\n revert(0, 0)\n }\n }\n }\n function g() external view returns (uint s, uint m, uint t) {\n assembly {\n s := sload(0)\n m := mload(0)\n t := tload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n// g() -> 0x2a, 0, 0\n" + }, + "blobhash_index_exceeding_blob_count.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n // EIP-4844 specifies that if `index < len(tx.blob_versioned_hashes)`, `blobhash(index)` should return 0.\n // Thus, as we injected only two blob hashes in the transaction context in EVMHost,\n // the return value of the function below MUST be zero.\n ret := blobhash(2)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x00\n" + }, + "shadowing_local_function_opcode.sol": { + "content": "contract C {\n function add(uint, uint) public pure returns (uint) { return 7; }\n function g() public pure returns (uint x, uint y) {\n x = add(1, 2);\n assembly {\n y := add(1, 2)\n }\n }\n}\n// ----\n// g() -> 7, 3\n" + }, + "calldata_length_read.sol": { + "content": "contract C {\n function lenBytesRead(bytes calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n\n function lenStringRead(string calldata x) public returns (uint l) {\n assembly { l := x.length }\n }\n}\n// ----\n// lenBytesRead(bytes): 0x20, 4, \"abcd\" -> 4\n// lenBytesRead(bytes): 0x20, 0, \"abcd\" -> 0x00\n// lenBytesRead(bytes): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n// lenStringRead(string): 0x20, 4, \"abcd\" -> 4\n// lenStringRead(string): 0x20, 0, \"abcd\" -> 0x00\n// lenStringRead(string): 0x20, 0x21, \"abcd\", \"ef\" -> 33\n" + }, + "mcopy_overlap.sol": { + "content": "function copy(uint dstOffset, uint srcOffset, uint length) pure returns (bytes memory out) {\n out =\n hex\"2222222222222222333333333333333344444444444444445555555555555555\"\n hex\"6666666666666666777777777777777788888888888888889999999999999999\"\n hex\"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\";\n assembly {\n mcopy(add(add(out, 0x20), dstOffset), add(add(out, 0x20), srcOffset), length)\n }\n}\n\ncontract C {\n function mcopy_to_right_overlap() public pure returns (bytes memory) {\n return copy(0x20, 0x10, 0x30);\n }\n\n function mcopy_to_left_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x20, 0x30);\n }\n\n function mcopy_in_place() public pure returns (bytes memory) {\n return copy(0x10, 0x10, 0x40);\n }\n\n function mcopy_to_right_no_overlap() public pure returns (bytes memory) {\n return copy(0x30, 0x10, 0x20);\n }\n\n function mcopy_to_left_no_overlap() public pure returns (bytes memory) {\n return copy(0x10, 0x30, 0x20);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// mcopy_to_right_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x4444444444444444555555555555555566666666666666667777777777777777, 0x88888888888888889999999999999999ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333366666666666666667777777777777777, 0x88888888888888889999999999999999aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_in_place() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777788888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n// mcopy_to_right_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333344444444444444445555555555555555, 0x6666666666666666777777777777777744444444444444445555555555555555, 0x66666666666666667777777777777777ccccccccccccccccdddddddddddddddd\n// mcopy_to_left_no_overlap() -> 0x20, 0x60, 0x2222222222222222333333333333333388888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb88888888888888889999999999999999, 0xaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd\n" + }, + "truefalse.sol": { + "content": "contract C {\n function f() public returns (uint x, uint y) {\n assembly {\n x := true\n y := false\n }\n }\n}\n// ----\n// f() -> 1, 0\n" + }, + "transient_storage_creation.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n" + }, + "external_identifier_access_shadowing.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n assembly {\n function g() -> f { f := 2 }\n x := g()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "calldata_offset_read.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (uint r) {\n assembly { r := x.offset }\n }\n\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x44\n// f(bytes): 0x22, 0, 0, 0 -> 0x46\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 0x84, 2\n// f(uint256,bytes,uint256): 0, 0, 0 -> 0x24, 0x00\n" + }, + "calldata_assign.sol": { + "content": "contract C {\n function f(bytes calldata x) public returns (bytes memory) {\n assembly { x.offset := 1 x.length := 3 }\n return x;\n }\n}\n// ----\n// f(bytes): 0x20, 0, 0 -> 0x20, 3, 0x5754f80000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_embedded_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d:= 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := g(a)\n function g(r) -> s {\n s := mul(r, r)\n }\n y := g(b)\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x4, 0x7, 0x10\n" + }, + "constant_access_referencing.sol": { + "content": "contract C {\n uint constant a = 2;\n uint constant aa = a;\n uint constant aaa = aa;\n bytes2 constant b = 0xabcd;\n bytes2 constant bb = b;\n bytes3 constant c = \"abc\";\n bytes3 constant cc = c;\n bytes3 constant ccc = cc;\n bytes3 constant cccc = ccc;\n bool constant d = true;\n bool constant dd = d;\n address constant e = 0x1212121212121212121212121212121212121212;\n address constant ee = e;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := aaa\n x := bb\n y := cccc\n z := dd\n t := ee\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "keccak256_optimizer_bug_different_memory_location.sol": { + "content": "contract C {\n function f() public view returns (bool ret) {\n assembly {\n let x := calldataload(0)\n mstore(0, x)\n mstore(0x20, x)\n let a := keccak256(0, 4)\n let b := keccak256(0x20, 8)\n ret := eq(a, b)\n }\n }\n}\n// ----\n// f() -> false\n" + }, + "external_function_pointer_selector.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul() public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\t\tuint selectorValue = 0;\n\n\t\tassembly {\n\t\t\tselectorValue := fp.selector\n\t\t}\n\n\t\t// Value is right-aligned, we shift it so it can be compared\n\t\treturn uint32(bytes4(bytes32(selectorValue << (256 - 32))));\n\t}\n\tfunction testSol() public returns (uint32) {\n\t\treturn uint32(this.testFunction.selector);\n\t}\n}\n// ----\n// testYul() -> 0xe16b4a9b\n// testSol() -> 0xe16b4a9b\n" + }, + "inline_assembly_in_modifiers.sol": { + "content": "contract C {\n modifier m {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2) revert();\n _;\n }\n\n function f() public m returns (bool) {\n return true;\n }\n\n modifier n {\n uint256 a = 1;\n assembly {\n a := 2\n }\n if (a != 2)\n _;\n revert();\n }\n\n function g() public n returns (bool) {\n // This statement should never execute.\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> FAILURE\n" + }, + "inline_assembly_recursion.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n function fac(n) -> nf {\n switch n\n case 0 {\n nf := 1\n }\n case 1 {\n nf := 1\n }\n default {\n nf := mul(n, fac(sub(n, 1)))\n }\n }\n b := fac(a)\n }\n }\n}\n// ----\n// f(uint256): 0 -> 1\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 3 -> 6\n// f(uint256): 4 -> 24\n" + }, + "calldata_struct_assign.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256 x; }\n\tstruct S2 { uint256 x; uint256 y; }\n\tfunction f(S calldata s, S2 calldata s2) public pure returns (uint256 r, uint256 r2) {\n\t\tassembly {\n\t\t\ts := s2\n\t\t\ts2 := 4\n\t\t}\n\t\tr = s.x;\n\t\tr2 = s2.x;\n\t}\n}\n// ----\n// f((uint256),(uint256,uint256)): 0x42, 0x07, 0x77 -> 0x07, 0x42\n" + }, + "inline_assembly_function_call.sol": { + "content": "contract C {\n function f() public {\n assembly {\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n return (0, 0x60)\n }\n }\n}\n// ----\n// f() -> 1, 2, 7\n" + }, + "blobbasefee_shanghai_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let blobbasefee := 999\n ret := blobbasefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobbasefee() -> r {\n r := 1000\n }\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// f() -> 999\n// g() -> 1000\n" + }, + "transient_storage_multiple_transactions.sol": { + "content": "contract C {\n function set(uint value) private {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() private view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function f() external {\n assembly {\n tstore(0, 42)\n }\n }\n\n function g() external view returns(uint r) {\n assembly {\n r := tload(0)\n }\n }\n\n function h() external returns (uint x) {\n set(99);\n x = get();\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// g() -> 0\n// f() ->\n// g() -> 0\n// h() -> 0x63\n// g() -> 0\n" + }, + "transient_storage_simple_reentrancy_lock.sol": { + "content": "contract C {\n modifier nonreentrant {\n assembly {\n if tload(0) { revert(0, 0) }\n tstore(0, 1)\n }\n _;\n assembly {\n tstore(0, 0)\n }\n }\n function f(bool simulateReentrancy) nonreentrant public {\n if (simulateReentrancy) {\n f(false);\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bool): false ->\n// f(bool): true -> FAILURE\n" + }, + "inline_assembly_switch.sol": { + "content": "contract C {\n function f(uint256 a) public returns (uint256 b) {\n assembly {\n switch a\n case 1 {\n b := 8\n }\n case 2 {\n b := 9\n }\n default {\n b := 2\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 2\n// f(uint256): 1 -> 8\n// f(uint256): 2 -> 9\n// f(uint256): 3 -> 2\n" + }, + "function_name_clash.sol": { + "content": "contract C {\n function f() public pure returns (uint r) {\n assembly { function f() -> x { x := 1 } r := f() }\n }\n function g() public pure returns (uint r) {\n assembly { function f() -> x { x := 2 } r := f() }\n }\n}\n// ----\n// f() -> 1\n// g() -> 2\n" + }, + "chainid.sol": { + "content": "contract C {\n function f() public returns (uint id) {\n assembly {\n id := chainid()\n }\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n" + }, + "inline_assembly_for2.sol": { + "content": "contract C {\n uint256 st;\n\n function f(uint256 a) public returns (uint256 b, uint256 c, uint256 d) {\n st = 0;\n assembly {\n function sideeffect(r) -> x {\n sstore(0, add(sload(0), r))\n x := 1\n }\n for {\n let i := a\n } eq(i, sideeffect(2)) {\n d := add(d, 3)\n } {\n b := i\n i := 0\n }\n }\n c = st;\n }\n}\n// ----\n// f(uint256): 0 -> 0, 2, 0\n// f(uint256): 1 -> 1, 4, 3\n// f(uint256): 2 -> 0, 2, 0\n" + }, + "transient_storage_selfdestruct.sol": { + "content": "contract C {\n function set(uint value) external {\n assembly {\n tstore(0, value)\n }\n }\n\n function get() external view returns (uint value) {\n assembly {\n value := tload(0)\n }\n }\n\n function terminate(address payable a) external {\n selfdestruct(a);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() {\n c = new C();\n }\n\n function destroy() external {\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n\n function createAndDestroy() external {\n c = new C();\n c.set(42);\n c.terminate(payable(address(this)));\n assert(c.get() == 42);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas irOptimized: 127596\n// gas irOptimized code: 221000\n// gas legacy: 149480\n// gas legacy code: 501200\n// gas legacyOptimized: 125846\n// gas legacyOptimized code: 203400\n// destroy() ->\n// createAndDestroy() ->\n// gas legacy: 67048\n// gas legacy code: 92600\n// gas legacyOptimized: 65677\n// gas legacyOptimized code: 39400\n" + }, + "external_function_pointer_selector_assignment.sol": { + "content": "contract C {\n\tfunction testFunction() external {}\n\n\tfunction testYul(uint32 newSelector) view public returns (uint32) {\n\t\tfunction() external fp = this.testFunction;\n\n\t\tassembly {\n\t\t\tfp.selector := newSelector\n\t\t}\n\n\t\treturn uint32(fp.selector);\n\t}\n}\n// ----\n// testYul(uint32): 0x12345678 -> 0x12345678\n// testYul(uint32): 0xABCDEF00 -> 0xABCDEF00\n" + }, + "transient_storage_multiple_calls_different_transactions.sol": { + "content": "contract C {\n function get(uint256 addr) external view returns (uint256 x) {\n assembly {\n x := tload(addr)\n }\n }\n function set(uint256 addr, uint256 x) external {\n assembly {\n tstore(addr, x)\n }\n }\n function test() public {\n assert(this.get(0) == 0 && this.get(42) == 0);\n this.set(0, 21);\n assert(this.get(0) == 21 && this.get(42) == 0);\n this.set(42, 131);\n assert(this.get(0) == 21 && this.get(42) == 131);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() ->\n// test() ->\n" + }, + "calldata_array_assign_static.sol": { + "content": "contract C {\n function f(uint[2][2] calldata x) public returns (uint[2][2] memory r) {\n assembly { x := 0x24 }\n r = x;\n }\n}\n// ----\n// f(uint256[2][2]): 0x0, 8, 7, 6, 5 -> 8, 7, 6, 5\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f() public view returns (bytes32 ret) {\n assembly {\n ret := blobhash(0)\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "inline_assembly_storage_access.sol": { + "content": "contract C {\n uint16 x;\n uint16 public y;\n uint256 public z;\n\n function f() public returns (bool) {\n uint256 off1;\n uint256 off2;\n assembly {\n sstore(z.slot, 7)\n off1 := z.offset\n off2 := y.offset\n }\n assert(off1 == 0);\n assert(off2 == 2);\n return true;\n }\n}\n// ----\n// f() -> true\n// z() -> 7\n" + }, + "prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := prevrandao()\n }\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "mcopy_as_identifier_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint result) {\n assembly {\n let mcopy := 1\n result := mcopy\n }\n }\n\n function g() public pure returns (uint result) {\n assembly {\n function mcopy() -> r {\n r := 1000\n }\n result := mcopy()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "constant_access.sol": { + "content": "contract C {\n uint constant a = 2;\n bytes2 constant b = 0xabcd;\n bytes3 constant c = \"abc\";\n bool constant d = true;\n address constant e = 0x1212121212121212121212121212121212121212;\n function f() public pure returns (uint w, bytes2 x, bytes3 y, bool z, address t) {\n assembly {\n w := a\n x := b\n y := c\n z := d\n t := e\n }\n }\n}\n// ----\n// f() -> 2, left(0xabcd), left(0x616263), true, 0x1212121212121212121212121212121212121212\n" + }, + "calldata_assign_from_nowhere.sol": { + "content": "contract C {\n function f() public pure returns (bytes calldata x) {\n assembly { x.offset := 0 x.length := 4 }\n }\n}\n// ----\n// f() -> 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n" + }, + "transient_storage_low_level_calls.sol": { + "content": "contract D {\n function addOne() external {\n assembly {\n let x := tload(0)\n tstore(0, add(x, 1))\n }\n }\n function get() external returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n}\n\ncontract C {\n function set(uint x) external {\n assembly {\n tstore(0, x)\n }\n }\n\n function get() external view returns (uint x) {\n assembly {\n x := tload(0)\n }\n }\n\n function testDelegateCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Caller contract is the owner of the transient storage\n (bool success, ) = address(d).delegatecall(abi.encodeCall(d.addOne, ()));\n require(success);\n require(this.get() == 6);\n return true;\n }\n\n function testCall() external returns (bool) {\n this.set(5);\n D d = new D();\n // Callee/Target contract is the owner of the transient storage\n (bool success, ) = address(d).call(abi.encodeCall(d.addOne, ()));\n require(success);\n require(d.get() == 1);\n return true;\n }\n\n function tloadAllowedStaticCall() external returns (bool) {\n this.set(5);\n D d = new D();\n (bool success, bytes memory result) = address(d).staticcall(abi.encodeCall(d.get, ()));\n require(success);\n require(abi.decode(result, (uint)) == 0);\n return true;\n }\n\n function tstoreNotAllowedStaticCall() external returns (bool) {\n D d = new D();\n (bool success, ) = address(d).staticcall(abi.encodeCall(d.addOne, ()));\n require(!success);\n return true;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegateCall() -> true\n// testCall() -> true\n// tloadAllowedStaticCall() -> true\n// tstoreNotAllowedStaticCall() -> true\n// gas irOptimized: 98419720\n// gas irOptimized code: 19000\n// gas legacy: 98409086\n// gas legacy code: 30000\n// gas legacyOptimized: 98420962\n// gas legacyOptimized code: 17800\n" + }, + "keccak256_assembly.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 ret) {\n assembly {\n ret := keccak256(0, 0)\n }\n }\n}\n// ----\n// f() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n" + }, + "inline_assembly_function_call2.sol": { + "content": "contract C {\n function f() public {\n assembly {\n let d := 0x10\n\n function asmfun(a, b, c) -> x, y, z {\n x := a\n y := b\n z := 7\n }\n let a1, b1, c1 := asmfun(1, 2, 3)\n mstore(0x00, a1)\n mstore(0x20, b1)\n mstore(0x40, c1)\n mstore(0x60, d)\n return (0, 0x80)\n }\n }\n}\n// ----\n// f() -> 0x1, 0x2, 0x7, 0x10\n" + }, + "basefee_berlin_function.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n let basefee := sload(0)\n ret := basefee\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function basefee() -> r {\n r := 1000\n }\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: <=berlin\n// ----\n// f() -> 0\n// g() -> 1000\n" + }, + "optimize_memory_store_multi_block_bugreport.sol": { + "content": "contract Test {\n\tuint256 x;\n\n\tfunction test() public returns (uint256) {\n\t\tuint256 a = myGetX();\n\t\tx = 5;\n\t\tuint256 b = myGetX();\n\t\tassembly {\n\t\t\tlog0(0, 64)\n\t\t}\n\t\treturn a + b + myGetX();\n\t}\n\n\tfunction myGetX() internal view returns (uint256) {\n\t\tassembly {\n\t\t\tmstore(1, 0x123456789abcdef)\n\t\t}\n\t\treturn x;\n\t}\n}\n// ----\n// test() -> 10\n// ~ emit : 0x0123456789abcd, 0xef00000000000000000000000000000000000000000000000000000000000000\n" + }, + "inline_assembly_transient_storage_access_inside_function.sol": { + "content": "contract C {\n uint16 transient x;\n uint16 public transient y;\n uint256 public transient z;\n\n function f() public returns (uint256) {\n uint256 offset;\n assembly {\n function f() -> o1 {\n tstore(z.slot, 7)\n o1 := y.offset\n }\n offset := f()\n }\n assert(offset == 2);\n return z;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 7\n" + }, + "mcopy.sol": { + "content": "contract C {\n function f(bytes memory src) public pure returns (bytes memory dst) {\n assembly {\n mcopy(add(dst, 0x1f), add(src, 0x1f), 0x01) // Copy over src length byte to dst\n mcopy(add(dst, 0x20), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n mcopy(add(dst, 0x28), add(src, 0x28), 0x10) // Copy 16 bytes from the middle of src to dst\n mcopy(add(dst, 0x38), add(src, 0x00), 0x08) // Copy 8 zero bytes to dst\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(bytes): 0x20, 0x20, 0xffeeddccbbaa9988776655443322110000112233445566778899aabbccddeeff -> 0x20, 0x20, 0x0000000000000000776655443322110000112233445566770000000000000000\n" + }, + "calldata_offset_read_write.sol": { + "content": "contract C {\n function f(uint, bytes calldata x, uint) public returns (uint r, uint v) {\n assembly {\n x.offset := 8\n x.length := 20\n }\n assembly {\n r := x.offset\n v := x.length\n }\n }\n}\n// ----\n// f(uint256,bytes,uint256): 7, 0x60, 8, 2, 0 -> 8, 0x14\n// f(uint256,bytes,uint256): 0, 0, 0 -> 8, 0x14\n" + }, + "leave.sol": { + "content": "contract C {\n function f() public pure returns (uint w) {\n assembly {\n function f() -> t {\n t := 2\n leave\n t := 9\n }\n w := f()\n }\n }\n}\n// ----\n// f() -> 2\n" + }, + "transient_storage_reset_between_creation_runtime.sol": { + "content": "contract C {\n constructor() {\n uint x;\n assembly {\n tstore(0, 42)\n x := tload(0)\n }\n assert(x == 42);\n }\n\n function f() public returns (uint x) {\n assembly {\n x := tload(0)\n if eq(x, 42) {\n revert(0, 0)\n }\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// f() -> 0\n" + }, + "slot_access_via_mapping_pointer.sol": { + "content": "contract C {\n mapping(uint => uint) private m0;\n mapping(uint => uint) private m1;\n mapping(uint => uint) private m2;\n\n function f(uint i) public returns (uint slot, uint offset) {\n mapping(uint => uint) storage m0Ptr = m0;\n mapping(uint => uint) storage m1Ptr = m1;\n mapping(uint => uint) storage m2Ptr = m2;\n\n assembly {\n switch i\n case 1 {\n slot := m1Ptr.slot\n offset := m1Ptr.offset\n }\n case 2 {\n slot := m2Ptr.slot\n offset := m2Ptr.offset\n }\n default {\n slot := m0Ptr.slot\n offset := m0Ptr.offset\n }\n }\n }\n}\n// ----\n// f(uint256): 0 -> 0, 0\n// f(uint256): 1 -> 1, 0\n// f(uint256): 2 -> 2, 0\n" + }, + "inline_assembly_storage_access_local_var.sol": { + "content": "contract C {\n uint256[] public a;\n\n function f() public returns (uint256) {\n uint256[] storage x = a;\n uint256 off;\n assembly {\n sstore(x.slot, 7)\n off := x.offset\n }\n assert(off == 0);\n return a.length;\n }\n}\n// ----\n// f() -> 7\n" + }, + "inline_assembly_read_and_write_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n for (uint256 x = 0; x < 10; ++x)\n assembly {\n r := add(r, x)\n }\n }\n}\n// ----\n// f() -> 45\n" + }, + "blobhash_pre_cancun.sol": { + "content": "contract C {\n function f() public pure returns (uint ret) {\n assembly {\n let blobhash := 1\n ret := blobhash\n }\n }\n function g() public pure returns (uint ret) {\n assembly {\n function blobhash() -> r {\n r := 1000\n }\n ret := blobhash()\n }\n }\n}\n// ====\n// EVMVersion: 1\n// g() -> 1000\n" + }, + "difficulty.sol": { + "content": "contract C {\n function f() public view returns (uint ret) {\n assembly {\n ret := difficulty()\n }\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "tstore_hidden_staticcall.sol": { + "content": "contract C {\n function f() internal {\n assembly {\n tstore(0, 0)\n }\n }\n function g() public view {\n function() internal ptr = f;\n function() internal view ptr2;\n assembly { ptr2 := ptr }\n ptr2(); // we force calling the non-view function, which should result in a revert during the staticcall\n }\n function test() public {\n this.g(); // an external call to a view function should use static call\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> FAILURE\n// gas irOptimized: 98437877\n// gas legacy: 98437871\n// gas legacyOptimized: 98437872\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/integer_basic/basic.sol b/examples/test/semanticTests/integer_basic/basic.sol new file mode 100644 index 00000000..cea56cd7 --- /dev/null +++ b/examples/test/semanticTests/integer_basic/basic.sol @@ -0,0 +1,22 @@ +contract C { + function basic() public pure returns(bool) { + uint uint_min = type(uint).min; + require(uint_min == 0); + + uint uint_max = type(uint).max; + require(uint_max == 2**256 - 1); + require(uint_max == 115792089237316195423570985008687907853269984665640564039457584007913129639935); + + int int_min = type(int).min; + require(int_min == -2**255); + require(int_min == -57896044618658097711785492504343953926634992332820282019728792003956564819968); + + int int_max = type(int).max; + require(int_max == 2**255 -1); + require(int_max == 57896044618658097711785492504343953926634992332820282019728792003956564819967); + + return true; + } +} +// ---- +// basic() -> true diff --git a/examples/test/semanticTests/integer_basic/basic_standard_input.json b/examples/test/semanticTests/integer_basic/basic_standard_input.json new file mode 100644 index 00000000..44d158cb --- /dev/null +++ b/examples/test/semanticTests/integer_basic/basic_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "uint.sol": { + "content": "contract test {\n\n\tfunction uintMinA() public pure returns(bool) {\n\n\t\tuint8 uint8_min = type(uint8).min;\n\t\trequire(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\trequire(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\trequire(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\trequire(uint32_min == 0);\n\n\t\tuint40 uint40_min = type(uint40).min;\n\t\trequire(uint40_min == 0);\n\n\t\tuint48 uint48_min = type(uint48).min;\n\t\trequire(uint48_min == 0);\n\n\t\tuint56 uint56_min = type(uint56).min;\n\t\trequire(uint56_min == 0);\n\n\t\tuint64 uint64_min = type(uint64).min;\n\t\trequire(uint64_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinB() public pure returns(bool) {\n\n\t\tuint72 uint72_min = type(uint72).min;\n\t\trequire(uint72_min == 0);\n\n\t\tuint80 uint80_min = type(uint80).min;\n\t\trequire(uint80_min == 0);\n\n\t\tuint88 uint88_min = type(uint88).min;\n\t\trequire(uint88_min == 0);\n\n\t\tuint96 uint96_min = type(uint96).min;\n\t\trequire(uint96_min == 0);\n\n\t\tuint104 uint104_min = type(uint104).min;\n\t\trequire(uint104_min == 0);\n\n\t\tuint112 uint112_min = type(uint112).min;\n\t\trequire(uint112_min == 0);\n\n\t\tuint120 uint120_min = type(uint120).min;\n\t\trequire(uint120_min == 0);\n\n\t\tuint128 uint128_min = type(uint128).min;\n\t\trequire(uint128_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinC() public pure returns(bool) {\n\n\t\tuint136 uint136_min = type(uint136).min;\n\t\trequire(uint136_min == 0);\n\n\t\tuint144 uint144_min = type(uint144).min;\n\t\trequire(uint144_min == 0);\n\n\t\tuint152 uint152_min = type(uint152).min;\n\t\trequire(uint152_min == 0);\n\n\t\tuint160 uint160_min = type(uint160).min;\n\t\trequire(uint160_min == 0);\n\n\t\tuint168 uint168_min = type(uint168).min;\n\t\trequire(uint168_min == 0);\n\n\t\tuint176 uint176_min = type(uint176).min;\n\t\trequire(uint176_min == 0);\n\n\t\tuint184 uint184_min = type(uint184).min;\n\t\trequire(uint184_min == 0);\n\n\t\tuint192 uint192_min = type(uint192).min;\n\t\trequire(uint192_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinD() public pure returns(bool) {\n\n\t\tuint200 uint200_min = type(uint200).min;\n\t\trequire(uint200_min == 0);\n\n\t\tuint208 uint208_min = type(uint208).min;\n\t\trequire(uint208_min == 0);\n\n\t\tuint216 uint216_min = type(uint216).min;\n\t\trequire(uint216_min == 0);\n\n\t\tuint224 uint224_min = type(uint224).min;\n\t\trequire(uint224_min == 0);\n\n\t\tuint232 uint232_min = type(uint232).min;\n\t\trequire(uint232_min == 0);\n\n\t\tuint240 uint240_min = type(uint240).min;\n\t\trequire(uint240_min == 0);\n\n\t\tuint248 uint248_min = type(uint248).min;\n\t\trequire(uint248_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\trequire(uint256_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxA() public pure returns (bool) {\n\n\t\tuint8 uint8_max = type(uint8).max;\n\t\trequire(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\trequire(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\trequire(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\trequire(uint32_max == 2**32-1);\n\n\t\tuint40 uint40_max = type(uint40).max;\n\t\trequire(uint40_max == 2**40-1);\n\n\t\tuint48 uint48_max = type(uint48).max;\n\t\trequire(uint48_max == 2**48-1);\n\n\t\tuint56 uint56_max = type(uint56).max;\n\t\trequire(uint56_max == 2**56-1);\n\n\t\tuint64 uint64_max = type(uint64).max;\n\t\trequire(uint64_max == 2**64-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxB() public pure returns (bool) {\n\n\t\tuint72 uint72_max = type(uint72).max;\n\t\trequire(uint72_max == 2**72-1);\n\n\t\tuint80 uint80_max = type(uint80).max;\n\t\trequire(uint80_max == 2**80-1);\n\n\t\tuint88 uint88_max = type(uint88).max;\n\t\trequire(uint88_max == 2**88-1);\n\n\t\tuint96 uint96_max = type(uint96).max;\n\t\trequire(uint96_max == 2**96-1);\n\n\t\tuint104 uint104_max = type(uint104).max;\n\t\trequire(uint104_max == 2**104-1);\n\n\t\tuint112 uint112_max = type(uint112).max;\n\t\trequire(uint112_max == 2**112-1);\n\n\t\tuint120 uint120_max = type(uint120).max;\n\t\trequire(uint120_max == 2**120-1);\n\n\t\tuint128 uint128_max = type(uint128).max;\n\t\trequire(uint128_max == 2**128-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxC() public pure returns (bool) {\n\n\t\tuint136 uint136_max = type(uint136).max;\n\t\trequire(uint136_max == 2**136-1);\n\n\t\tuint144 uint144_max = type(uint144).max;\n\t\trequire(uint144_max == 2**144-1);\n\n\t\tuint152 uint152_max = type(uint152).max;\n\t\trequire(uint152_max == 2**152-1);\n\n\t\tuint160 uint160_max = type(uint160).max;\n\t\trequire(uint160_max == 2**160-1);\n\n\t\tuint168 uint168_max = type(uint168).max;\n\t\trequire(uint168_max == 2**168-1);\n\n\t\tuint176 uint176_max = type(uint176).max;\n\t\trequire(uint176_max == 2**176-1);\n\n\t\tuint184 uint184_max = type(uint184).max;\n\t\trequire(uint184_max == 2**184-1);\n\n\t\tuint192 uint192_max = type(uint192).max;\n\t\trequire(uint192_max == 2**192-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxD() public pure returns(bool) {\n\t\tuint200 uint200_max = type(uint200).max;\n\t\trequire(uint200_max == 2**200-1);\n\n\t\tuint208 uint208_max = type(uint208).max;\n\t\trequire(uint208_max == 2**208-1);\n\n\t\tuint216 uint216_max = type(uint216).max;\n\t\trequire(uint216_max == 2**216-1);\n\n\t\tuint224 uint224_max = type(uint224).max;\n\t\trequire(uint224_max == 2**224-1);\n\n\t\tuint232 uint232_max = type(uint232).max;\n\t\trequire(uint232_max == 2**232-1);\n\n\t\tuint240 uint240_max = type(uint240).max;\n\t\trequire(uint240_max == 2**240-1);\n\n\t\tuint248 uint248_max = type(uint248).max;\n\t\trequire(uint248_max == 2**248-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\trequire(uint256_max == 2**256-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// uintMinA() -> true\n// uintMinB() -> true\n// uintMinC() -> true\n// uintMinD() -> true\n// uintMaxA() -> true\n// uintMaxB() -> true\n// uintMaxC() -> true\n// uintMaxD() -> true\n" + }, + "int.sol": { + "content": "contract test {\n\n\tfunction intMinA() public pure returns (bool) {\n\n\t\tint8 int8_min = type(int8).min;\n\t\trequire(int8_min == -2**7);\n\n\t\tint16 int16_min = type(int16).min;\n\t\trequire(int16_min == -2**15);\n\n\t\tint24 int24_min = type(int24).min;\n\t\trequire(int24_min == -2**23);\n\n\t\tint32 int32_min = type(int32).min;\n\t\trequire(int32_min == -2**31);\n\n\t\tint40 int40_min = type(int40).min;\n\t\trequire(int40_min == -2**39);\n\n\t\tint48 int48_min = type(int48).min;\n\t\trequire(int48_min == -2**47);\n\n\t\tint56 int56_min = type(int56).min;\n\t\trequire(int56_min == -2**55);\n\n\t\tint64 int64_min = type(int64).min;\n\t\trequire(int64_min == -2**63);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinB() public pure returns(bool) {\n\n\t\tint72 int72_min = type(int72).min;\n\t\trequire(int72_min == -2**71);\n\n\t\tint80 int80_min = type(int80).min;\n\t\trequire(int80_min == -2**79);\n\n\t\tint88 int88_min = type(int88).min;\n\t\trequire(int88_min == -2**87);\n\n\t\tint96 int96_min = type(int96).min;\n\t\trequire(int96_min == -2**95);\n\n\t\tint104 int104_min = type(int104).min;\n\t\trequire(int104_min == -2**103);\n\n\t\tint112 int112_min = type(int112).min;\n\t\trequire(int112_min == -2**111);\n\n\t\tint120 int120_min = type(int120).min;\n\t\trequire(int120_min == -2**119);\n\n\t\tint128 int128_min = type(int128).min;\n\t\trequire(int128_min == -2**127);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinC() public pure returns (bool) {\n\n\t\tint136 int136_min = type(int136).min;\n\t\trequire(int136_min == -2**135);\n\n\t\tint144 int144_min = type(int144).min;\n\t\trequire(int144_min == -2**143);\n\n\t\tint152 int152_min = type(int152).min;\n\t\trequire(int152_min == -2**151);\n\n\t\tint160 int160_min = type(int160).min;\n\t\trequire(int160_min == -2**159);\n\n\t\tint168 int168_min = type(int168).min;\n\t\trequire(int168_min == -2**167);\n\n\t\tint176 int176_min = type(int176).min;\n\t\trequire(int176_min == -2**175);\n\n\t\tint184 int184_min = type(int184).min;\n\t\trequire(int184_min == -2**183);\n\n\t\tint192 int192_min = type(int192).min;\n\t\trequire(int192_min == -2**191);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinD() public pure returns(bool) {\n\n\t\tint200 int200_min = type(int200).min;\n\t\trequire(int200_min == -2**199);\n\n\t\tint208 int208_min = type(int208).min;\n\t\trequire(int208_min == -2**207);\n\n\t\tint216 int216_min = type(int216).min;\n\t\trequire(int216_min == -2**215);\n\n\t\tint224 int224_min = type(int224).min;\n\t\trequire(int224_min == -2**223);\n\n\t\tint232 int232_min = type(int232).min;\n\t\trequire(int232_min == -2**231);\n\n\t\tint240 int240_min = type(int240).min;\n\t\trequire(int240_min == -2**239);\n\n\t\tint248 int248_min = type(int248).min;\n\t\trequire(int248_min == -2**247);\n\n\t\tint256 int256_min = type(int256).min;\n\t\trequire(int256_min == -2**255);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxA() public pure returns (bool) {\n\n\t\tint8 int8_max = type(int8).max;\n\t\trequire(int8_max == 2**7-1);\n\n\t\tint16 int16_max = type(int16).max;\n\t\trequire(int16_max == 2**15-1);\n\n\t\tint24 int24_max = type(int24).max;\n\t\trequire(int24_max == 2**23-1);\n\n\t\tint32 int32_max = type(int32).max;\n\t\trequire(int32_max == 2**31-1);\n\n\t\tint40 int40_max = type(int40).max;\n\t\trequire(int40_max == 2**39-1);\n\n\t\tint48 int48_max = type(int48).max;\n\t\trequire(int48_max == 2**47-1);\n\n\t\tint56 int56_max = type(int56).max;\n\t\trequire(int56_max == 2**55-1);\n\n\t\tint64 int64_max = type(int64).max;\n\t\trequire(int64_max == 2**63-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxB() public pure returns(bool) {\n\n\t\tint72 int72_max = type(int72).max;\n\t\trequire(int72_max == 2**71-1);\n\n\t\tint80 int80_max = type(int80).max;\n\t\trequire(int80_max == 2**79-1);\n\n\t\tint88 int88_max = type(int88).max;\n\t\trequire(int88_max == 2**87-1);\n\n\t\tint96 int96_max = type(int96).max;\n\t\trequire(int96_max == 2**95-1);\n\n\t\tint104 int104_max = type(int104).max;\n\t\trequire(int104_max == 2**103-1);\n\n\t\tint112 int112_max = type(int112).max;\n\t\trequire(int112_max == 2**111-1);\n\n\t\tint120 int120_max = type(int120).max;\n\t\trequire(int120_max == 2**119-1);\n\n\t\tint128 int128_max = type(int128).max;\n\t\trequire(int128_max == 2**127-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxC() public pure returns (bool) {\n\n\t\tint136 int136_max = type(int136).max;\n\t\trequire(int136_max == 2**135-1);\n\n\t\tint144 int144_max = type(int144).max;\n\t\trequire(int144_max == 2**143-1);\n\n\t\tint152 int152_max = type(int152).max;\n\t\trequire(int152_max == 2**151-1);\n\n\t\tint160 int160_max = type(int160).max;\n\t\trequire(int160_max == 2**159-1);\n\n\t\tint168 int168_max = type(int168).max;\n\t\trequire(int168_max == 2**167-1);\n\n\t\tint176 int176_max = type(int176).max;\n\t\trequire(int176_max == 2**175-1);\n\n\t\tint184 int184_max = type(int184).max;\n\t\trequire(int184_max == 2**183-1);\n\n\t\tint192 int192_max = type(int192).max;\n\t\trequire(int192_max == 2**191-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxD() public pure returns(bool) {\n\n\t\tint200 int200_max = type(int200).max;\n\t\trequire(int200_max == 2**199-1);\n\n\t\tint208 int208_max = type(int208).max;\n\t\trequire(int208_max == 2**207-1);\n\n\t\tint216 int216_max = type(int216).max;\n\t\trequire(int216_max == 2**215-1);\n\n\t\tint224 int224_max = type(int224).max;\n\t\trequire(int224_max == 2**223-1);\n\n\t\tint232 int232_max = type(int232).max;\n\t\trequire(int232_max == 2**231-1);\n\n\t\tint240 int240_max = type(int240).max;\n\t\trequire(int240_max == 2**239-1);\n\n\t\tint248 int248_max = type(int248).max;\n\t\trequire(int248_max == 2**247-1);\n\n\t\tint256 int256_max = type(int256).max;\n\t\trequire(int256_max == 2**255-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// intMinA() -> true\n// intMinB() -> true\n// intMinC() -> true\n// intMinD() -> true\n// intMaxA() -> true\n// intMaxB() -> true\n// intMaxC() -> true\n// intMaxD() -> true\n" + }, + "small_signed_types.sol": { + "content": "contract test {\n function run() public returns(int256 y) {\n return -int32(10) * -int64(20);\n }\n}\n// ----\n// run() -> 200\n" + }, + "many_local_variables.sol": { + "content": "contract test {\n function run(uint x1, uint x2, uint x3) public returns(uint y) {\n uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;\n y = a + b + c + x1 + x2 + x3;\n y += b + x2;\n }\n}\n// ----\n// run(uint256,uint256,uint256): 0x1000, 0x10000, 0x100000 -> 0x121121\n" + }, + "basic.sol": { + "content": "contract C {\n\tfunction basic() public pure returns(bool) {\n\t\tuint uint_min = type(uint).min;\n\t\trequire(uint_min == 0);\n\n\t\tuint uint_max = type(uint).max;\n\t\trequire(uint_max == 2**256 - 1);\n\t\trequire(uint_max == 115792089237316195423570985008687907853269984665640564039457584007913129639935);\n\n\t\tint int_min = type(int).min;\n\t\trequire(int_min == -2**255);\n\t\trequire(int_min == -57896044618658097711785492504343953926634992332820282019728792003956564819968);\n\n\t\tint int_max = type(int).max;\n\t\trequire(int_max == 2**255 -1);\n\t\trequire(int_max == 57896044618658097711785492504343953926634992332820282019728792003956564819967);\n\n\t\treturn true;\n\t}\n}\n// ----\n// basic() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/integer_int/int.sol b/examples/test/semanticTests/integer_int/int.sol new file mode 100644 index 00000000..d3681a0e --- /dev/null +++ b/examples/test/semanticTests/integer_int/int.sol @@ -0,0 +1,243 @@ +contract test { + + function intMinA() public pure returns (bool) { + + int8 int8_min = type(int8).min; + require(int8_min == -2**7); + + int16 int16_min = type(int16).min; + require(int16_min == -2**15); + + int24 int24_min = type(int24).min; + require(int24_min == -2**23); + + int32 int32_min = type(int32).min; + require(int32_min == -2**31); + + int40 int40_min = type(int40).min; + require(int40_min == -2**39); + + int48 int48_min = type(int48).min; + require(int48_min == -2**47); + + int56 int56_min = type(int56).min; + require(int56_min == -2**55); + + int64 int64_min = type(int64).min; + require(int64_min == -2**63); + + return true; + } + + function intMinB() public pure returns(bool) { + + int72 int72_min = type(int72).min; + require(int72_min == -2**71); + + int80 int80_min = type(int80).min; + require(int80_min == -2**79); + + int88 int88_min = type(int88).min; + require(int88_min == -2**87); + + int96 int96_min = type(int96).min; + require(int96_min == -2**95); + + int104 int104_min = type(int104).min; + require(int104_min == -2**103); + + int112 int112_min = type(int112).min; + require(int112_min == -2**111); + + int120 int120_min = type(int120).min; + require(int120_min == -2**119); + + int128 int128_min = type(int128).min; + require(int128_min == -2**127); + + return true; + } + + function intMinC() public pure returns (bool) { + + int136 int136_min = type(int136).min; + require(int136_min == -2**135); + + int144 int144_min = type(int144).min; + require(int144_min == -2**143); + + int152 int152_min = type(int152).min; + require(int152_min == -2**151); + + int160 int160_min = type(int160).min; + require(int160_min == -2**159); + + int168 int168_min = type(int168).min; + require(int168_min == -2**167); + + int176 int176_min = type(int176).min; + require(int176_min == -2**175); + + int184 int184_min = type(int184).min; + require(int184_min == -2**183); + + int192 int192_min = type(int192).min; + require(int192_min == -2**191); + + return true; + } + + function intMinD() public pure returns(bool) { + + int200 int200_min = type(int200).min; + require(int200_min == -2**199); + + int208 int208_min = type(int208).min; + require(int208_min == -2**207); + + int216 int216_min = type(int216).min; + require(int216_min == -2**215); + + int224 int224_min = type(int224).min; + require(int224_min == -2**223); + + int232 int232_min = type(int232).min; + require(int232_min == -2**231); + + int240 int240_min = type(int240).min; + require(int240_min == -2**239); + + int248 int248_min = type(int248).min; + require(int248_min == -2**247); + + int256 int256_min = type(int256).min; + require(int256_min == -2**255); + + return true; + } + + function intMaxA() public pure returns (bool) { + + int8 int8_max = type(int8).max; + require(int8_max == 2**7-1); + + int16 int16_max = type(int16).max; + require(int16_max == 2**15-1); + + int24 int24_max = type(int24).max; + require(int24_max == 2**23-1); + + int32 int32_max = type(int32).max; + require(int32_max == 2**31-1); + + int40 int40_max = type(int40).max; + require(int40_max == 2**39-1); + + int48 int48_max = type(int48).max; + require(int48_max == 2**47-1); + + int56 int56_max = type(int56).max; + require(int56_max == 2**55-1); + + int64 int64_max = type(int64).max; + require(int64_max == 2**63-1); + + return true; + } + + function intMaxB() public pure returns(bool) { + + int72 int72_max = type(int72).max; + require(int72_max == 2**71-1); + + int80 int80_max = type(int80).max; + require(int80_max == 2**79-1); + + int88 int88_max = type(int88).max; + require(int88_max == 2**87-1); + + int96 int96_max = type(int96).max; + require(int96_max == 2**95-1); + + int104 int104_max = type(int104).max; + require(int104_max == 2**103-1); + + int112 int112_max = type(int112).max; + require(int112_max == 2**111-1); + + int120 int120_max = type(int120).max; + require(int120_max == 2**119-1); + + int128 int128_max = type(int128).max; + require(int128_max == 2**127-1); + + return true; + } + + function intMaxC() public pure returns (bool) { + + int136 int136_max = type(int136).max; + require(int136_max == 2**135-1); + + int144 int144_max = type(int144).max; + require(int144_max == 2**143-1); + + int152 int152_max = type(int152).max; + require(int152_max == 2**151-1); + + int160 int160_max = type(int160).max; + require(int160_max == 2**159-1); + + int168 int168_max = type(int168).max; + require(int168_max == 2**167-1); + + int176 int176_max = type(int176).max; + require(int176_max == 2**175-1); + + int184 int184_max = type(int184).max; + require(int184_max == 2**183-1); + + int192 int192_max = type(int192).max; + require(int192_max == 2**191-1); + + return true; + } + + function intMaxD() public pure returns(bool) { + + int200 int200_max = type(int200).max; + require(int200_max == 2**199-1); + + int208 int208_max = type(int208).max; + require(int208_max == 2**207-1); + + int216 int216_max = type(int216).max; + require(int216_max == 2**215-1); + + int224 int224_max = type(int224).max; + require(int224_max == 2**223-1); + + int232 int232_max = type(int232).max; + require(int232_max == 2**231-1); + + int240 int240_max = type(int240).max; + require(int240_max == 2**239-1); + + int248 int248_max = type(int248).max; + require(int248_max == 2**247-1); + + int256 int256_max = type(int256).max; + require(int256_max == 2**255-1); + + return true; + } +} +// ---- +// intMinA() -> true +// intMinB() -> true +// intMinC() -> true +// intMinD() -> true +// intMaxA() -> true +// intMaxB() -> true +// intMaxC() -> true +// intMaxD() -> true diff --git a/examples/test/semanticTests/integer_int/int_standard_input.json b/examples/test/semanticTests/integer_int/int_standard_input.json new file mode 100644 index 00000000..4e4961d6 --- /dev/null +++ b/examples/test/semanticTests/integer_int/int_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "uint.sol": { + "content": "contract test {\n\n\tfunction uintMinA() public pure returns(bool) {\n\n\t\tuint8 uint8_min = type(uint8).min;\n\t\trequire(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\trequire(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\trequire(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\trequire(uint32_min == 0);\n\n\t\tuint40 uint40_min = type(uint40).min;\n\t\trequire(uint40_min == 0);\n\n\t\tuint48 uint48_min = type(uint48).min;\n\t\trequire(uint48_min == 0);\n\n\t\tuint56 uint56_min = type(uint56).min;\n\t\trequire(uint56_min == 0);\n\n\t\tuint64 uint64_min = type(uint64).min;\n\t\trequire(uint64_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinB() public pure returns(bool) {\n\n\t\tuint72 uint72_min = type(uint72).min;\n\t\trequire(uint72_min == 0);\n\n\t\tuint80 uint80_min = type(uint80).min;\n\t\trequire(uint80_min == 0);\n\n\t\tuint88 uint88_min = type(uint88).min;\n\t\trequire(uint88_min == 0);\n\n\t\tuint96 uint96_min = type(uint96).min;\n\t\trequire(uint96_min == 0);\n\n\t\tuint104 uint104_min = type(uint104).min;\n\t\trequire(uint104_min == 0);\n\n\t\tuint112 uint112_min = type(uint112).min;\n\t\trequire(uint112_min == 0);\n\n\t\tuint120 uint120_min = type(uint120).min;\n\t\trequire(uint120_min == 0);\n\n\t\tuint128 uint128_min = type(uint128).min;\n\t\trequire(uint128_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinC() public pure returns(bool) {\n\n\t\tuint136 uint136_min = type(uint136).min;\n\t\trequire(uint136_min == 0);\n\n\t\tuint144 uint144_min = type(uint144).min;\n\t\trequire(uint144_min == 0);\n\n\t\tuint152 uint152_min = type(uint152).min;\n\t\trequire(uint152_min == 0);\n\n\t\tuint160 uint160_min = type(uint160).min;\n\t\trequire(uint160_min == 0);\n\n\t\tuint168 uint168_min = type(uint168).min;\n\t\trequire(uint168_min == 0);\n\n\t\tuint176 uint176_min = type(uint176).min;\n\t\trequire(uint176_min == 0);\n\n\t\tuint184 uint184_min = type(uint184).min;\n\t\trequire(uint184_min == 0);\n\n\t\tuint192 uint192_min = type(uint192).min;\n\t\trequire(uint192_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinD() public pure returns(bool) {\n\n\t\tuint200 uint200_min = type(uint200).min;\n\t\trequire(uint200_min == 0);\n\n\t\tuint208 uint208_min = type(uint208).min;\n\t\trequire(uint208_min == 0);\n\n\t\tuint216 uint216_min = type(uint216).min;\n\t\trequire(uint216_min == 0);\n\n\t\tuint224 uint224_min = type(uint224).min;\n\t\trequire(uint224_min == 0);\n\n\t\tuint232 uint232_min = type(uint232).min;\n\t\trequire(uint232_min == 0);\n\n\t\tuint240 uint240_min = type(uint240).min;\n\t\trequire(uint240_min == 0);\n\n\t\tuint248 uint248_min = type(uint248).min;\n\t\trequire(uint248_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\trequire(uint256_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxA() public pure returns (bool) {\n\n\t\tuint8 uint8_max = type(uint8).max;\n\t\trequire(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\trequire(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\trequire(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\trequire(uint32_max == 2**32-1);\n\n\t\tuint40 uint40_max = type(uint40).max;\n\t\trequire(uint40_max == 2**40-1);\n\n\t\tuint48 uint48_max = type(uint48).max;\n\t\trequire(uint48_max == 2**48-1);\n\n\t\tuint56 uint56_max = type(uint56).max;\n\t\trequire(uint56_max == 2**56-1);\n\n\t\tuint64 uint64_max = type(uint64).max;\n\t\trequire(uint64_max == 2**64-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxB() public pure returns (bool) {\n\n\t\tuint72 uint72_max = type(uint72).max;\n\t\trequire(uint72_max == 2**72-1);\n\n\t\tuint80 uint80_max = type(uint80).max;\n\t\trequire(uint80_max == 2**80-1);\n\n\t\tuint88 uint88_max = type(uint88).max;\n\t\trequire(uint88_max == 2**88-1);\n\n\t\tuint96 uint96_max = type(uint96).max;\n\t\trequire(uint96_max == 2**96-1);\n\n\t\tuint104 uint104_max = type(uint104).max;\n\t\trequire(uint104_max == 2**104-1);\n\n\t\tuint112 uint112_max = type(uint112).max;\n\t\trequire(uint112_max == 2**112-1);\n\n\t\tuint120 uint120_max = type(uint120).max;\n\t\trequire(uint120_max == 2**120-1);\n\n\t\tuint128 uint128_max = type(uint128).max;\n\t\trequire(uint128_max == 2**128-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxC() public pure returns (bool) {\n\n\t\tuint136 uint136_max = type(uint136).max;\n\t\trequire(uint136_max == 2**136-1);\n\n\t\tuint144 uint144_max = type(uint144).max;\n\t\trequire(uint144_max == 2**144-1);\n\n\t\tuint152 uint152_max = type(uint152).max;\n\t\trequire(uint152_max == 2**152-1);\n\n\t\tuint160 uint160_max = type(uint160).max;\n\t\trequire(uint160_max == 2**160-1);\n\n\t\tuint168 uint168_max = type(uint168).max;\n\t\trequire(uint168_max == 2**168-1);\n\n\t\tuint176 uint176_max = type(uint176).max;\n\t\trequire(uint176_max == 2**176-1);\n\n\t\tuint184 uint184_max = type(uint184).max;\n\t\trequire(uint184_max == 2**184-1);\n\n\t\tuint192 uint192_max = type(uint192).max;\n\t\trequire(uint192_max == 2**192-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxD() public pure returns(bool) {\n\t\tuint200 uint200_max = type(uint200).max;\n\t\trequire(uint200_max == 2**200-1);\n\n\t\tuint208 uint208_max = type(uint208).max;\n\t\trequire(uint208_max == 2**208-1);\n\n\t\tuint216 uint216_max = type(uint216).max;\n\t\trequire(uint216_max == 2**216-1);\n\n\t\tuint224 uint224_max = type(uint224).max;\n\t\trequire(uint224_max == 2**224-1);\n\n\t\tuint232 uint232_max = type(uint232).max;\n\t\trequire(uint232_max == 2**232-1);\n\n\t\tuint240 uint240_max = type(uint240).max;\n\t\trequire(uint240_max == 2**240-1);\n\n\t\tuint248 uint248_max = type(uint248).max;\n\t\trequire(uint248_max == 2**248-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\trequire(uint256_max == 2**256-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// uintMinA() -> true\n// uintMinB() -> true\n// uintMinC() -> true\n// uintMinD() -> true\n// uintMaxA() -> true\n// uintMaxB() -> true\n// uintMaxC() -> true\n// uintMaxD() -> true\n" + }, + "int.sol": { + "content": "contract test {\n\n\tfunction intMinA() public pure returns (bool) {\n\n\t\tint8 int8_min = type(int8).min;\n\t\trequire(int8_min == -2**7);\n\n\t\tint16 int16_min = type(int16).min;\n\t\trequire(int16_min == -2**15);\n\n\t\tint24 int24_min = type(int24).min;\n\t\trequire(int24_min == -2**23);\n\n\t\tint32 int32_min = type(int32).min;\n\t\trequire(int32_min == -2**31);\n\n\t\tint40 int40_min = type(int40).min;\n\t\trequire(int40_min == -2**39);\n\n\t\tint48 int48_min = type(int48).min;\n\t\trequire(int48_min == -2**47);\n\n\t\tint56 int56_min = type(int56).min;\n\t\trequire(int56_min == -2**55);\n\n\t\tint64 int64_min = type(int64).min;\n\t\trequire(int64_min == -2**63);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinB() public pure returns(bool) {\n\n\t\tint72 int72_min = type(int72).min;\n\t\trequire(int72_min == -2**71);\n\n\t\tint80 int80_min = type(int80).min;\n\t\trequire(int80_min == -2**79);\n\n\t\tint88 int88_min = type(int88).min;\n\t\trequire(int88_min == -2**87);\n\n\t\tint96 int96_min = type(int96).min;\n\t\trequire(int96_min == -2**95);\n\n\t\tint104 int104_min = type(int104).min;\n\t\trequire(int104_min == -2**103);\n\n\t\tint112 int112_min = type(int112).min;\n\t\trequire(int112_min == -2**111);\n\n\t\tint120 int120_min = type(int120).min;\n\t\trequire(int120_min == -2**119);\n\n\t\tint128 int128_min = type(int128).min;\n\t\trequire(int128_min == -2**127);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinC() public pure returns (bool) {\n\n\t\tint136 int136_min = type(int136).min;\n\t\trequire(int136_min == -2**135);\n\n\t\tint144 int144_min = type(int144).min;\n\t\trequire(int144_min == -2**143);\n\n\t\tint152 int152_min = type(int152).min;\n\t\trequire(int152_min == -2**151);\n\n\t\tint160 int160_min = type(int160).min;\n\t\trequire(int160_min == -2**159);\n\n\t\tint168 int168_min = type(int168).min;\n\t\trequire(int168_min == -2**167);\n\n\t\tint176 int176_min = type(int176).min;\n\t\trequire(int176_min == -2**175);\n\n\t\tint184 int184_min = type(int184).min;\n\t\trequire(int184_min == -2**183);\n\n\t\tint192 int192_min = type(int192).min;\n\t\trequire(int192_min == -2**191);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinD() public pure returns(bool) {\n\n\t\tint200 int200_min = type(int200).min;\n\t\trequire(int200_min == -2**199);\n\n\t\tint208 int208_min = type(int208).min;\n\t\trequire(int208_min == -2**207);\n\n\t\tint216 int216_min = type(int216).min;\n\t\trequire(int216_min == -2**215);\n\n\t\tint224 int224_min = type(int224).min;\n\t\trequire(int224_min == -2**223);\n\n\t\tint232 int232_min = type(int232).min;\n\t\trequire(int232_min == -2**231);\n\n\t\tint240 int240_min = type(int240).min;\n\t\trequire(int240_min == -2**239);\n\n\t\tint248 int248_min = type(int248).min;\n\t\trequire(int248_min == -2**247);\n\n\t\tint256 int256_min = type(int256).min;\n\t\trequire(int256_min == -2**255);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxA() public pure returns (bool) {\n\n\t\tint8 int8_max = type(int8).max;\n\t\trequire(int8_max == 2**7-1);\n\n\t\tint16 int16_max = type(int16).max;\n\t\trequire(int16_max == 2**15-1);\n\n\t\tint24 int24_max = type(int24).max;\n\t\trequire(int24_max == 2**23-1);\n\n\t\tint32 int32_max = type(int32).max;\n\t\trequire(int32_max == 2**31-1);\n\n\t\tint40 int40_max = type(int40).max;\n\t\trequire(int40_max == 2**39-1);\n\n\t\tint48 int48_max = type(int48).max;\n\t\trequire(int48_max == 2**47-1);\n\n\t\tint56 int56_max = type(int56).max;\n\t\trequire(int56_max == 2**55-1);\n\n\t\tint64 int64_max = type(int64).max;\n\t\trequire(int64_max == 2**63-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxB() public pure returns(bool) {\n\n\t\tint72 int72_max = type(int72).max;\n\t\trequire(int72_max == 2**71-1);\n\n\t\tint80 int80_max = type(int80).max;\n\t\trequire(int80_max == 2**79-1);\n\n\t\tint88 int88_max = type(int88).max;\n\t\trequire(int88_max == 2**87-1);\n\n\t\tint96 int96_max = type(int96).max;\n\t\trequire(int96_max == 2**95-1);\n\n\t\tint104 int104_max = type(int104).max;\n\t\trequire(int104_max == 2**103-1);\n\n\t\tint112 int112_max = type(int112).max;\n\t\trequire(int112_max == 2**111-1);\n\n\t\tint120 int120_max = type(int120).max;\n\t\trequire(int120_max == 2**119-1);\n\n\t\tint128 int128_max = type(int128).max;\n\t\trequire(int128_max == 2**127-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxC() public pure returns (bool) {\n\n\t\tint136 int136_max = type(int136).max;\n\t\trequire(int136_max == 2**135-1);\n\n\t\tint144 int144_max = type(int144).max;\n\t\trequire(int144_max == 2**143-1);\n\n\t\tint152 int152_max = type(int152).max;\n\t\trequire(int152_max == 2**151-1);\n\n\t\tint160 int160_max = type(int160).max;\n\t\trequire(int160_max == 2**159-1);\n\n\t\tint168 int168_max = type(int168).max;\n\t\trequire(int168_max == 2**167-1);\n\n\t\tint176 int176_max = type(int176).max;\n\t\trequire(int176_max == 2**175-1);\n\n\t\tint184 int184_max = type(int184).max;\n\t\trequire(int184_max == 2**183-1);\n\n\t\tint192 int192_max = type(int192).max;\n\t\trequire(int192_max == 2**191-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxD() public pure returns(bool) {\n\n\t\tint200 int200_max = type(int200).max;\n\t\trequire(int200_max == 2**199-1);\n\n\t\tint208 int208_max = type(int208).max;\n\t\trequire(int208_max == 2**207-1);\n\n\t\tint216 int216_max = type(int216).max;\n\t\trequire(int216_max == 2**215-1);\n\n\t\tint224 int224_max = type(int224).max;\n\t\trequire(int224_max == 2**223-1);\n\n\t\tint232 int232_max = type(int232).max;\n\t\trequire(int232_max == 2**231-1);\n\n\t\tint240 int240_max = type(int240).max;\n\t\trequire(int240_max == 2**239-1);\n\n\t\tint248 int248_max = type(int248).max;\n\t\trequire(int248_max == 2**247-1);\n\n\t\tint256 int256_max = type(int256).max;\n\t\trequire(int256_max == 2**255-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// intMinA() -> true\n// intMinB() -> true\n// intMinC() -> true\n// intMinD() -> true\n// intMaxA() -> true\n// intMaxB() -> true\n// intMaxC() -> true\n// intMaxD() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/integer_many_local_variables/many_local_variables.sol b/examples/test/semanticTests/integer_many_local_variables/many_local_variables.sol new file mode 100644 index 00000000..c43f9269 --- /dev/null +++ b/examples/test/semanticTests/integer_many_local_variables/many_local_variables.sol @@ -0,0 +1,9 @@ +contract test { + function run(uint x1, uint x2, uint x3) public returns(uint y) { + uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100; + y = a + b + c + x1 + x2 + x3; + y += b + x2; + } +} +// ---- +// run(uint256,uint256,uint256): 0x1000, 0x10000, 0x100000 -> 0x121121 diff --git a/examples/test/semanticTests/integer_many_local_variables/many_local_variables_standard_input.json b/examples/test/semanticTests/integer_many_local_variables/many_local_variables_standard_input.json new file mode 100644 index 00000000..761b2c93 --- /dev/null +++ b/examples/test/semanticTests/integer_many_local_variables/many_local_variables_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "uint.sol": { + "content": "contract test {\n\n\tfunction uintMinA() public pure returns(bool) {\n\n\t\tuint8 uint8_min = type(uint8).min;\n\t\trequire(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\trequire(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\trequire(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\trequire(uint32_min == 0);\n\n\t\tuint40 uint40_min = type(uint40).min;\n\t\trequire(uint40_min == 0);\n\n\t\tuint48 uint48_min = type(uint48).min;\n\t\trequire(uint48_min == 0);\n\n\t\tuint56 uint56_min = type(uint56).min;\n\t\trequire(uint56_min == 0);\n\n\t\tuint64 uint64_min = type(uint64).min;\n\t\trequire(uint64_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinB() public pure returns(bool) {\n\n\t\tuint72 uint72_min = type(uint72).min;\n\t\trequire(uint72_min == 0);\n\n\t\tuint80 uint80_min = type(uint80).min;\n\t\trequire(uint80_min == 0);\n\n\t\tuint88 uint88_min = type(uint88).min;\n\t\trequire(uint88_min == 0);\n\n\t\tuint96 uint96_min = type(uint96).min;\n\t\trequire(uint96_min == 0);\n\n\t\tuint104 uint104_min = type(uint104).min;\n\t\trequire(uint104_min == 0);\n\n\t\tuint112 uint112_min = type(uint112).min;\n\t\trequire(uint112_min == 0);\n\n\t\tuint120 uint120_min = type(uint120).min;\n\t\trequire(uint120_min == 0);\n\n\t\tuint128 uint128_min = type(uint128).min;\n\t\trequire(uint128_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinC() public pure returns(bool) {\n\n\t\tuint136 uint136_min = type(uint136).min;\n\t\trequire(uint136_min == 0);\n\n\t\tuint144 uint144_min = type(uint144).min;\n\t\trequire(uint144_min == 0);\n\n\t\tuint152 uint152_min = type(uint152).min;\n\t\trequire(uint152_min == 0);\n\n\t\tuint160 uint160_min = type(uint160).min;\n\t\trequire(uint160_min == 0);\n\n\t\tuint168 uint168_min = type(uint168).min;\n\t\trequire(uint168_min == 0);\n\n\t\tuint176 uint176_min = type(uint176).min;\n\t\trequire(uint176_min == 0);\n\n\t\tuint184 uint184_min = type(uint184).min;\n\t\trequire(uint184_min == 0);\n\n\t\tuint192 uint192_min = type(uint192).min;\n\t\trequire(uint192_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinD() public pure returns(bool) {\n\n\t\tuint200 uint200_min = type(uint200).min;\n\t\trequire(uint200_min == 0);\n\n\t\tuint208 uint208_min = type(uint208).min;\n\t\trequire(uint208_min == 0);\n\n\t\tuint216 uint216_min = type(uint216).min;\n\t\trequire(uint216_min == 0);\n\n\t\tuint224 uint224_min = type(uint224).min;\n\t\trequire(uint224_min == 0);\n\n\t\tuint232 uint232_min = type(uint232).min;\n\t\trequire(uint232_min == 0);\n\n\t\tuint240 uint240_min = type(uint240).min;\n\t\trequire(uint240_min == 0);\n\n\t\tuint248 uint248_min = type(uint248).min;\n\t\trequire(uint248_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\trequire(uint256_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxA() public pure returns (bool) {\n\n\t\tuint8 uint8_max = type(uint8).max;\n\t\trequire(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\trequire(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\trequire(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\trequire(uint32_max == 2**32-1);\n\n\t\tuint40 uint40_max = type(uint40).max;\n\t\trequire(uint40_max == 2**40-1);\n\n\t\tuint48 uint48_max = type(uint48).max;\n\t\trequire(uint48_max == 2**48-1);\n\n\t\tuint56 uint56_max = type(uint56).max;\n\t\trequire(uint56_max == 2**56-1);\n\n\t\tuint64 uint64_max = type(uint64).max;\n\t\trequire(uint64_max == 2**64-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxB() public pure returns (bool) {\n\n\t\tuint72 uint72_max = type(uint72).max;\n\t\trequire(uint72_max == 2**72-1);\n\n\t\tuint80 uint80_max = type(uint80).max;\n\t\trequire(uint80_max == 2**80-1);\n\n\t\tuint88 uint88_max = type(uint88).max;\n\t\trequire(uint88_max == 2**88-1);\n\n\t\tuint96 uint96_max = type(uint96).max;\n\t\trequire(uint96_max == 2**96-1);\n\n\t\tuint104 uint104_max = type(uint104).max;\n\t\trequire(uint104_max == 2**104-1);\n\n\t\tuint112 uint112_max = type(uint112).max;\n\t\trequire(uint112_max == 2**112-1);\n\n\t\tuint120 uint120_max = type(uint120).max;\n\t\trequire(uint120_max == 2**120-1);\n\n\t\tuint128 uint128_max = type(uint128).max;\n\t\trequire(uint128_max == 2**128-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxC() public pure returns (bool) {\n\n\t\tuint136 uint136_max = type(uint136).max;\n\t\trequire(uint136_max == 2**136-1);\n\n\t\tuint144 uint144_max = type(uint144).max;\n\t\trequire(uint144_max == 2**144-1);\n\n\t\tuint152 uint152_max = type(uint152).max;\n\t\trequire(uint152_max == 2**152-1);\n\n\t\tuint160 uint160_max = type(uint160).max;\n\t\trequire(uint160_max == 2**160-1);\n\n\t\tuint168 uint168_max = type(uint168).max;\n\t\trequire(uint168_max == 2**168-1);\n\n\t\tuint176 uint176_max = type(uint176).max;\n\t\trequire(uint176_max == 2**176-1);\n\n\t\tuint184 uint184_max = type(uint184).max;\n\t\trequire(uint184_max == 2**184-1);\n\n\t\tuint192 uint192_max = type(uint192).max;\n\t\trequire(uint192_max == 2**192-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxD() public pure returns(bool) {\n\t\tuint200 uint200_max = type(uint200).max;\n\t\trequire(uint200_max == 2**200-1);\n\n\t\tuint208 uint208_max = type(uint208).max;\n\t\trequire(uint208_max == 2**208-1);\n\n\t\tuint216 uint216_max = type(uint216).max;\n\t\trequire(uint216_max == 2**216-1);\n\n\t\tuint224 uint224_max = type(uint224).max;\n\t\trequire(uint224_max == 2**224-1);\n\n\t\tuint232 uint232_max = type(uint232).max;\n\t\trequire(uint232_max == 2**232-1);\n\n\t\tuint240 uint240_max = type(uint240).max;\n\t\trequire(uint240_max == 2**240-1);\n\n\t\tuint248 uint248_max = type(uint248).max;\n\t\trequire(uint248_max == 2**248-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\trequire(uint256_max == 2**256-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// uintMinA() -> true\n// uintMinB() -> true\n// uintMinC() -> true\n// uintMinD() -> true\n// uintMaxA() -> true\n// uintMaxB() -> true\n// uintMaxC() -> true\n// uintMaxD() -> true\n" + }, + "int.sol": { + "content": "contract test {\n\n\tfunction intMinA() public pure returns (bool) {\n\n\t\tint8 int8_min = type(int8).min;\n\t\trequire(int8_min == -2**7);\n\n\t\tint16 int16_min = type(int16).min;\n\t\trequire(int16_min == -2**15);\n\n\t\tint24 int24_min = type(int24).min;\n\t\trequire(int24_min == -2**23);\n\n\t\tint32 int32_min = type(int32).min;\n\t\trequire(int32_min == -2**31);\n\n\t\tint40 int40_min = type(int40).min;\n\t\trequire(int40_min == -2**39);\n\n\t\tint48 int48_min = type(int48).min;\n\t\trequire(int48_min == -2**47);\n\n\t\tint56 int56_min = type(int56).min;\n\t\trequire(int56_min == -2**55);\n\n\t\tint64 int64_min = type(int64).min;\n\t\trequire(int64_min == -2**63);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinB() public pure returns(bool) {\n\n\t\tint72 int72_min = type(int72).min;\n\t\trequire(int72_min == -2**71);\n\n\t\tint80 int80_min = type(int80).min;\n\t\trequire(int80_min == -2**79);\n\n\t\tint88 int88_min = type(int88).min;\n\t\trequire(int88_min == -2**87);\n\n\t\tint96 int96_min = type(int96).min;\n\t\trequire(int96_min == -2**95);\n\n\t\tint104 int104_min = type(int104).min;\n\t\trequire(int104_min == -2**103);\n\n\t\tint112 int112_min = type(int112).min;\n\t\trequire(int112_min == -2**111);\n\n\t\tint120 int120_min = type(int120).min;\n\t\trequire(int120_min == -2**119);\n\n\t\tint128 int128_min = type(int128).min;\n\t\trequire(int128_min == -2**127);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinC() public pure returns (bool) {\n\n\t\tint136 int136_min = type(int136).min;\n\t\trequire(int136_min == -2**135);\n\n\t\tint144 int144_min = type(int144).min;\n\t\trequire(int144_min == -2**143);\n\n\t\tint152 int152_min = type(int152).min;\n\t\trequire(int152_min == -2**151);\n\n\t\tint160 int160_min = type(int160).min;\n\t\trequire(int160_min == -2**159);\n\n\t\tint168 int168_min = type(int168).min;\n\t\trequire(int168_min == -2**167);\n\n\t\tint176 int176_min = type(int176).min;\n\t\trequire(int176_min == -2**175);\n\n\t\tint184 int184_min = type(int184).min;\n\t\trequire(int184_min == -2**183);\n\n\t\tint192 int192_min = type(int192).min;\n\t\trequire(int192_min == -2**191);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinD() public pure returns(bool) {\n\n\t\tint200 int200_min = type(int200).min;\n\t\trequire(int200_min == -2**199);\n\n\t\tint208 int208_min = type(int208).min;\n\t\trequire(int208_min == -2**207);\n\n\t\tint216 int216_min = type(int216).min;\n\t\trequire(int216_min == -2**215);\n\n\t\tint224 int224_min = type(int224).min;\n\t\trequire(int224_min == -2**223);\n\n\t\tint232 int232_min = type(int232).min;\n\t\trequire(int232_min == -2**231);\n\n\t\tint240 int240_min = type(int240).min;\n\t\trequire(int240_min == -2**239);\n\n\t\tint248 int248_min = type(int248).min;\n\t\trequire(int248_min == -2**247);\n\n\t\tint256 int256_min = type(int256).min;\n\t\trequire(int256_min == -2**255);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxA() public pure returns (bool) {\n\n\t\tint8 int8_max = type(int8).max;\n\t\trequire(int8_max == 2**7-1);\n\n\t\tint16 int16_max = type(int16).max;\n\t\trequire(int16_max == 2**15-1);\n\n\t\tint24 int24_max = type(int24).max;\n\t\trequire(int24_max == 2**23-1);\n\n\t\tint32 int32_max = type(int32).max;\n\t\trequire(int32_max == 2**31-1);\n\n\t\tint40 int40_max = type(int40).max;\n\t\trequire(int40_max == 2**39-1);\n\n\t\tint48 int48_max = type(int48).max;\n\t\trequire(int48_max == 2**47-1);\n\n\t\tint56 int56_max = type(int56).max;\n\t\trequire(int56_max == 2**55-1);\n\n\t\tint64 int64_max = type(int64).max;\n\t\trequire(int64_max == 2**63-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxB() public pure returns(bool) {\n\n\t\tint72 int72_max = type(int72).max;\n\t\trequire(int72_max == 2**71-1);\n\n\t\tint80 int80_max = type(int80).max;\n\t\trequire(int80_max == 2**79-1);\n\n\t\tint88 int88_max = type(int88).max;\n\t\trequire(int88_max == 2**87-1);\n\n\t\tint96 int96_max = type(int96).max;\n\t\trequire(int96_max == 2**95-1);\n\n\t\tint104 int104_max = type(int104).max;\n\t\trequire(int104_max == 2**103-1);\n\n\t\tint112 int112_max = type(int112).max;\n\t\trequire(int112_max == 2**111-1);\n\n\t\tint120 int120_max = type(int120).max;\n\t\trequire(int120_max == 2**119-1);\n\n\t\tint128 int128_max = type(int128).max;\n\t\trequire(int128_max == 2**127-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxC() public pure returns (bool) {\n\n\t\tint136 int136_max = type(int136).max;\n\t\trequire(int136_max == 2**135-1);\n\n\t\tint144 int144_max = type(int144).max;\n\t\trequire(int144_max == 2**143-1);\n\n\t\tint152 int152_max = type(int152).max;\n\t\trequire(int152_max == 2**151-1);\n\n\t\tint160 int160_max = type(int160).max;\n\t\trequire(int160_max == 2**159-1);\n\n\t\tint168 int168_max = type(int168).max;\n\t\trequire(int168_max == 2**167-1);\n\n\t\tint176 int176_max = type(int176).max;\n\t\trequire(int176_max == 2**175-1);\n\n\t\tint184 int184_max = type(int184).max;\n\t\trequire(int184_max == 2**183-1);\n\n\t\tint192 int192_max = type(int192).max;\n\t\trequire(int192_max == 2**191-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxD() public pure returns(bool) {\n\n\t\tint200 int200_max = type(int200).max;\n\t\trequire(int200_max == 2**199-1);\n\n\t\tint208 int208_max = type(int208).max;\n\t\trequire(int208_max == 2**207-1);\n\n\t\tint216 int216_max = type(int216).max;\n\t\trequire(int216_max == 2**215-1);\n\n\t\tint224 int224_max = type(int224).max;\n\t\trequire(int224_max == 2**223-1);\n\n\t\tint232 int232_max = type(int232).max;\n\t\trequire(int232_max == 2**231-1);\n\n\t\tint240 int240_max = type(int240).max;\n\t\trequire(int240_max == 2**239-1);\n\n\t\tint248 int248_max = type(int248).max;\n\t\trequire(int248_max == 2**247-1);\n\n\t\tint256 int256_max = type(int256).max;\n\t\trequire(int256_max == 2**255-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// intMinA() -> true\n// intMinB() -> true\n// intMinC() -> true\n// intMinD() -> true\n// intMaxA() -> true\n// intMaxB() -> true\n// intMaxC() -> true\n// intMaxD() -> true\n" + }, + "small_signed_types.sol": { + "content": "contract test {\n function run() public returns(int256 y) {\n return -int32(10) * -int64(20);\n }\n}\n// ----\n// run() -> 200\n" + }, + "many_local_variables.sol": { + "content": "contract test {\n function run(uint x1, uint x2, uint x3) public returns(uint y) {\n uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;\n y = a + b + c + x1 + x2 + x3;\n y += b + x2;\n }\n}\n// ----\n// run(uint256,uint256,uint256): 0x1000, 0x10000, 0x100000 -> 0x121121\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/integer_small_signed_types/small_signed_types.sol b/examples/test/semanticTests/integer_small_signed_types/small_signed_types.sol new file mode 100644 index 00000000..4c0311e5 --- /dev/null +++ b/examples/test/semanticTests/integer_small_signed_types/small_signed_types.sol @@ -0,0 +1,7 @@ +contract test { + function run() public returns(int256 y) { + return -int32(10) * -int64(20); + } +} +// ---- +// run() -> 200 diff --git a/examples/test/semanticTests/integer_small_signed_types/small_signed_types_standard_input.json b/examples/test/semanticTests/integer_small_signed_types/small_signed_types_standard_input.json new file mode 100644 index 00000000..79591de4 --- /dev/null +++ b/examples/test/semanticTests/integer_small_signed_types/small_signed_types_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "uint.sol": { + "content": "contract test {\n\n\tfunction uintMinA() public pure returns(bool) {\n\n\t\tuint8 uint8_min = type(uint8).min;\n\t\trequire(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\trequire(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\trequire(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\trequire(uint32_min == 0);\n\n\t\tuint40 uint40_min = type(uint40).min;\n\t\trequire(uint40_min == 0);\n\n\t\tuint48 uint48_min = type(uint48).min;\n\t\trequire(uint48_min == 0);\n\n\t\tuint56 uint56_min = type(uint56).min;\n\t\trequire(uint56_min == 0);\n\n\t\tuint64 uint64_min = type(uint64).min;\n\t\trequire(uint64_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinB() public pure returns(bool) {\n\n\t\tuint72 uint72_min = type(uint72).min;\n\t\trequire(uint72_min == 0);\n\n\t\tuint80 uint80_min = type(uint80).min;\n\t\trequire(uint80_min == 0);\n\n\t\tuint88 uint88_min = type(uint88).min;\n\t\trequire(uint88_min == 0);\n\n\t\tuint96 uint96_min = type(uint96).min;\n\t\trequire(uint96_min == 0);\n\n\t\tuint104 uint104_min = type(uint104).min;\n\t\trequire(uint104_min == 0);\n\n\t\tuint112 uint112_min = type(uint112).min;\n\t\trequire(uint112_min == 0);\n\n\t\tuint120 uint120_min = type(uint120).min;\n\t\trequire(uint120_min == 0);\n\n\t\tuint128 uint128_min = type(uint128).min;\n\t\trequire(uint128_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinC() public pure returns(bool) {\n\n\t\tuint136 uint136_min = type(uint136).min;\n\t\trequire(uint136_min == 0);\n\n\t\tuint144 uint144_min = type(uint144).min;\n\t\trequire(uint144_min == 0);\n\n\t\tuint152 uint152_min = type(uint152).min;\n\t\trequire(uint152_min == 0);\n\n\t\tuint160 uint160_min = type(uint160).min;\n\t\trequire(uint160_min == 0);\n\n\t\tuint168 uint168_min = type(uint168).min;\n\t\trequire(uint168_min == 0);\n\n\t\tuint176 uint176_min = type(uint176).min;\n\t\trequire(uint176_min == 0);\n\n\t\tuint184 uint184_min = type(uint184).min;\n\t\trequire(uint184_min == 0);\n\n\t\tuint192 uint192_min = type(uint192).min;\n\t\trequire(uint192_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinD() public pure returns(bool) {\n\n\t\tuint200 uint200_min = type(uint200).min;\n\t\trequire(uint200_min == 0);\n\n\t\tuint208 uint208_min = type(uint208).min;\n\t\trequire(uint208_min == 0);\n\n\t\tuint216 uint216_min = type(uint216).min;\n\t\trequire(uint216_min == 0);\n\n\t\tuint224 uint224_min = type(uint224).min;\n\t\trequire(uint224_min == 0);\n\n\t\tuint232 uint232_min = type(uint232).min;\n\t\trequire(uint232_min == 0);\n\n\t\tuint240 uint240_min = type(uint240).min;\n\t\trequire(uint240_min == 0);\n\n\t\tuint248 uint248_min = type(uint248).min;\n\t\trequire(uint248_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\trequire(uint256_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxA() public pure returns (bool) {\n\n\t\tuint8 uint8_max = type(uint8).max;\n\t\trequire(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\trequire(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\trequire(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\trequire(uint32_max == 2**32-1);\n\n\t\tuint40 uint40_max = type(uint40).max;\n\t\trequire(uint40_max == 2**40-1);\n\n\t\tuint48 uint48_max = type(uint48).max;\n\t\trequire(uint48_max == 2**48-1);\n\n\t\tuint56 uint56_max = type(uint56).max;\n\t\trequire(uint56_max == 2**56-1);\n\n\t\tuint64 uint64_max = type(uint64).max;\n\t\trequire(uint64_max == 2**64-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxB() public pure returns (bool) {\n\n\t\tuint72 uint72_max = type(uint72).max;\n\t\trequire(uint72_max == 2**72-1);\n\n\t\tuint80 uint80_max = type(uint80).max;\n\t\trequire(uint80_max == 2**80-1);\n\n\t\tuint88 uint88_max = type(uint88).max;\n\t\trequire(uint88_max == 2**88-1);\n\n\t\tuint96 uint96_max = type(uint96).max;\n\t\trequire(uint96_max == 2**96-1);\n\n\t\tuint104 uint104_max = type(uint104).max;\n\t\trequire(uint104_max == 2**104-1);\n\n\t\tuint112 uint112_max = type(uint112).max;\n\t\trequire(uint112_max == 2**112-1);\n\n\t\tuint120 uint120_max = type(uint120).max;\n\t\trequire(uint120_max == 2**120-1);\n\n\t\tuint128 uint128_max = type(uint128).max;\n\t\trequire(uint128_max == 2**128-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxC() public pure returns (bool) {\n\n\t\tuint136 uint136_max = type(uint136).max;\n\t\trequire(uint136_max == 2**136-1);\n\n\t\tuint144 uint144_max = type(uint144).max;\n\t\trequire(uint144_max == 2**144-1);\n\n\t\tuint152 uint152_max = type(uint152).max;\n\t\trequire(uint152_max == 2**152-1);\n\n\t\tuint160 uint160_max = type(uint160).max;\n\t\trequire(uint160_max == 2**160-1);\n\n\t\tuint168 uint168_max = type(uint168).max;\n\t\trequire(uint168_max == 2**168-1);\n\n\t\tuint176 uint176_max = type(uint176).max;\n\t\trequire(uint176_max == 2**176-1);\n\n\t\tuint184 uint184_max = type(uint184).max;\n\t\trequire(uint184_max == 2**184-1);\n\n\t\tuint192 uint192_max = type(uint192).max;\n\t\trequire(uint192_max == 2**192-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxD() public pure returns(bool) {\n\t\tuint200 uint200_max = type(uint200).max;\n\t\trequire(uint200_max == 2**200-1);\n\n\t\tuint208 uint208_max = type(uint208).max;\n\t\trequire(uint208_max == 2**208-1);\n\n\t\tuint216 uint216_max = type(uint216).max;\n\t\trequire(uint216_max == 2**216-1);\n\n\t\tuint224 uint224_max = type(uint224).max;\n\t\trequire(uint224_max == 2**224-1);\n\n\t\tuint232 uint232_max = type(uint232).max;\n\t\trequire(uint232_max == 2**232-1);\n\n\t\tuint240 uint240_max = type(uint240).max;\n\t\trequire(uint240_max == 2**240-1);\n\n\t\tuint248 uint248_max = type(uint248).max;\n\t\trequire(uint248_max == 2**248-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\trequire(uint256_max == 2**256-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// uintMinA() -> true\n// uintMinB() -> true\n// uintMinC() -> true\n// uintMinD() -> true\n// uintMaxA() -> true\n// uintMaxB() -> true\n// uintMaxC() -> true\n// uintMaxD() -> true\n" + }, + "int.sol": { + "content": "contract test {\n\n\tfunction intMinA() public pure returns (bool) {\n\n\t\tint8 int8_min = type(int8).min;\n\t\trequire(int8_min == -2**7);\n\n\t\tint16 int16_min = type(int16).min;\n\t\trequire(int16_min == -2**15);\n\n\t\tint24 int24_min = type(int24).min;\n\t\trequire(int24_min == -2**23);\n\n\t\tint32 int32_min = type(int32).min;\n\t\trequire(int32_min == -2**31);\n\n\t\tint40 int40_min = type(int40).min;\n\t\trequire(int40_min == -2**39);\n\n\t\tint48 int48_min = type(int48).min;\n\t\trequire(int48_min == -2**47);\n\n\t\tint56 int56_min = type(int56).min;\n\t\trequire(int56_min == -2**55);\n\n\t\tint64 int64_min = type(int64).min;\n\t\trequire(int64_min == -2**63);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinB() public pure returns(bool) {\n\n\t\tint72 int72_min = type(int72).min;\n\t\trequire(int72_min == -2**71);\n\n\t\tint80 int80_min = type(int80).min;\n\t\trequire(int80_min == -2**79);\n\n\t\tint88 int88_min = type(int88).min;\n\t\trequire(int88_min == -2**87);\n\n\t\tint96 int96_min = type(int96).min;\n\t\trequire(int96_min == -2**95);\n\n\t\tint104 int104_min = type(int104).min;\n\t\trequire(int104_min == -2**103);\n\n\t\tint112 int112_min = type(int112).min;\n\t\trequire(int112_min == -2**111);\n\n\t\tint120 int120_min = type(int120).min;\n\t\trequire(int120_min == -2**119);\n\n\t\tint128 int128_min = type(int128).min;\n\t\trequire(int128_min == -2**127);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinC() public pure returns (bool) {\n\n\t\tint136 int136_min = type(int136).min;\n\t\trequire(int136_min == -2**135);\n\n\t\tint144 int144_min = type(int144).min;\n\t\trequire(int144_min == -2**143);\n\n\t\tint152 int152_min = type(int152).min;\n\t\trequire(int152_min == -2**151);\n\n\t\tint160 int160_min = type(int160).min;\n\t\trequire(int160_min == -2**159);\n\n\t\tint168 int168_min = type(int168).min;\n\t\trequire(int168_min == -2**167);\n\n\t\tint176 int176_min = type(int176).min;\n\t\trequire(int176_min == -2**175);\n\n\t\tint184 int184_min = type(int184).min;\n\t\trequire(int184_min == -2**183);\n\n\t\tint192 int192_min = type(int192).min;\n\t\trequire(int192_min == -2**191);\n\n\t\treturn true;\n\t}\n\n\tfunction intMinD() public pure returns(bool) {\n\n\t\tint200 int200_min = type(int200).min;\n\t\trequire(int200_min == -2**199);\n\n\t\tint208 int208_min = type(int208).min;\n\t\trequire(int208_min == -2**207);\n\n\t\tint216 int216_min = type(int216).min;\n\t\trequire(int216_min == -2**215);\n\n\t\tint224 int224_min = type(int224).min;\n\t\trequire(int224_min == -2**223);\n\n\t\tint232 int232_min = type(int232).min;\n\t\trequire(int232_min == -2**231);\n\n\t\tint240 int240_min = type(int240).min;\n\t\trequire(int240_min == -2**239);\n\n\t\tint248 int248_min = type(int248).min;\n\t\trequire(int248_min == -2**247);\n\n\t\tint256 int256_min = type(int256).min;\n\t\trequire(int256_min == -2**255);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxA() public pure returns (bool) {\n\n\t\tint8 int8_max = type(int8).max;\n\t\trequire(int8_max == 2**7-1);\n\n\t\tint16 int16_max = type(int16).max;\n\t\trequire(int16_max == 2**15-1);\n\n\t\tint24 int24_max = type(int24).max;\n\t\trequire(int24_max == 2**23-1);\n\n\t\tint32 int32_max = type(int32).max;\n\t\trequire(int32_max == 2**31-1);\n\n\t\tint40 int40_max = type(int40).max;\n\t\trequire(int40_max == 2**39-1);\n\n\t\tint48 int48_max = type(int48).max;\n\t\trequire(int48_max == 2**47-1);\n\n\t\tint56 int56_max = type(int56).max;\n\t\trequire(int56_max == 2**55-1);\n\n\t\tint64 int64_max = type(int64).max;\n\t\trequire(int64_max == 2**63-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxB() public pure returns(bool) {\n\n\t\tint72 int72_max = type(int72).max;\n\t\trequire(int72_max == 2**71-1);\n\n\t\tint80 int80_max = type(int80).max;\n\t\trequire(int80_max == 2**79-1);\n\n\t\tint88 int88_max = type(int88).max;\n\t\trequire(int88_max == 2**87-1);\n\n\t\tint96 int96_max = type(int96).max;\n\t\trequire(int96_max == 2**95-1);\n\n\t\tint104 int104_max = type(int104).max;\n\t\trequire(int104_max == 2**103-1);\n\n\t\tint112 int112_max = type(int112).max;\n\t\trequire(int112_max == 2**111-1);\n\n\t\tint120 int120_max = type(int120).max;\n\t\trequire(int120_max == 2**119-1);\n\n\t\tint128 int128_max = type(int128).max;\n\t\trequire(int128_max == 2**127-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxC() public pure returns (bool) {\n\n\t\tint136 int136_max = type(int136).max;\n\t\trequire(int136_max == 2**135-1);\n\n\t\tint144 int144_max = type(int144).max;\n\t\trequire(int144_max == 2**143-1);\n\n\t\tint152 int152_max = type(int152).max;\n\t\trequire(int152_max == 2**151-1);\n\n\t\tint160 int160_max = type(int160).max;\n\t\trequire(int160_max == 2**159-1);\n\n\t\tint168 int168_max = type(int168).max;\n\t\trequire(int168_max == 2**167-1);\n\n\t\tint176 int176_max = type(int176).max;\n\t\trequire(int176_max == 2**175-1);\n\n\t\tint184 int184_max = type(int184).max;\n\t\trequire(int184_max == 2**183-1);\n\n\t\tint192 int192_max = type(int192).max;\n\t\trequire(int192_max == 2**191-1);\n\n\t\treturn true;\n\t}\n\n\tfunction intMaxD() public pure returns(bool) {\n\n\t\tint200 int200_max = type(int200).max;\n\t\trequire(int200_max == 2**199-1);\n\n\t\tint208 int208_max = type(int208).max;\n\t\trequire(int208_max == 2**207-1);\n\n\t\tint216 int216_max = type(int216).max;\n\t\trequire(int216_max == 2**215-1);\n\n\t\tint224 int224_max = type(int224).max;\n\t\trequire(int224_max == 2**223-1);\n\n\t\tint232 int232_max = type(int232).max;\n\t\trequire(int232_max == 2**231-1);\n\n\t\tint240 int240_max = type(int240).max;\n\t\trequire(int240_max == 2**239-1);\n\n\t\tint248 int248_max = type(int248).max;\n\t\trequire(int248_max == 2**247-1);\n\n\t\tint256 int256_max = type(int256).max;\n\t\trequire(int256_max == 2**255-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// intMinA() -> true\n// intMinB() -> true\n// intMinC() -> true\n// intMinD() -> true\n// intMaxA() -> true\n// intMaxB() -> true\n// intMaxC() -> true\n// intMaxD() -> true\n" + }, + "small_signed_types.sol": { + "content": "contract test {\n function run() public returns(int256 y) {\n return -int32(10) * -int64(20);\n }\n}\n// ----\n// run() -> 200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/integer_uint/uint.sol b/examples/test/semanticTests/integer_uint/uint.sol new file mode 100644 index 00000000..ccd32fab --- /dev/null +++ b/examples/test/semanticTests/integer_uint/uint.sol @@ -0,0 +1,242 @@ +contract test { + + function uintMinA() public pure returns(bool) { + + uint8 uint8_min = type(uint8).min; + require(uint8_min == 0); + + uint16 uint16_min = type(uint16).min; + require(uint16_min == 0); + + uint24 uint24_min = type(uint24).min; + require(uint24_min == 0); + + uint32 uint32_min = type(uint32).min; + require(uint32_min == 0); + + uint40 uint40_min = type(uint40).min; + require(uint40_min == 0); + + uint48 uint48_min = type(uint48).min; + require(uint48_min == 0); + + uint56 uint56_min = type(uint56).min; + require(uint56_min == 0); + + uint64 uint64_min = type(uint64).min; + require(uint64_min == 0); + + return true; + } + + function uintMinB() public pure returns(bool) { + + uint72 uint72_min = type(uint72).min; + require(uint72_min == 0); + + uint80 uint80_min = type(uint80).min; + require(uint80_min == 0); + + uint88 uint88_min = type(uint88).min; + require(uint88_min == 0); + + uint96 uint96_min = type(uint96).min; + require(uint96_min == 0); + + uint104 uint104_min = type(uint104).min; + require(uint104_min == 0); + + uint112 uint112_min = type(uint112).min; + require(uint112_min == 0); + + uint120 uint120_min = type(uint120).min; + require(uint120_min == 0); + + uint128 uint128_min = type(uint128).min; + require(uint128_min == 0); + + return true; + } + + function uintMinC() public pure returns(bool) { + + uint136 uint136_min = type(uint136).min; + require(uint136_min == 0); + + uint144 uint144_min = type(uint144).min; + require(uint144_min == 0); + + uint152 uint152_min = type(uint152).min; + require(uint152_min == 0); + + uint160 uint160_min = type(uint160).min; + require(uint160_min == 0); + + uint168 uint168_min = type(uint168).min; + require(uint168_min == 0); + + uint176 uint176_min = type(uint176).min; + require(uint176_min == 0); + + uint184 uint184_min = type(uint184).min; + require(uint184_min == 0); + + uint192 uint192_min = type(uint192).min; + require(uint192_min == 0); + + return true; + } + + function uintMinD() public pure returns(bool) { + + uint200 uint200_min = type(uint200).min; + require(uint200_min == 0); + + uint208 uint208_min = type(uint208).min; + require(uint208_min == 0); + + uint216 uint216_min = type(uint216).min; + require(uint216_min == 0); + + uint224 uint224_min = type(uint224).min; + require(uint224_min == 0); + + uint232 uint232_min = type(uint232).min; + require(uint232_min == 0); + + uint240 uint240_min = type(uint240).min; + require(uint240_min == 0); + + uint248 uint248_min = type(uint248).min; + require(uint248_min == 0); + + uint256 uint256_min = type(uint256).min; + require(uint256_min == 0); + + return true; + } + + function uintMaxA() public pure returns (bool) { + + uint8 uint8_max = type(uint8).max; + require(uint8_max == 2**8-1); + + uint16 uint16_max = type(uint16).max; + require(uint16_max == 2**16-1); + + uint24 uint24_max = type(uint24).max; + require(uint24_max == 2**24-1); + + uint32 uint32_max = type(uint32).max; + require(uint32_max == 2**32-1); + + uint40 uint40_max = type(uint40).max; + require(uint40_max == 2**40-1); + + uint48 uint48_max = type(uint48).max; + require(uint48_max == 2**48-1); + + uint56 uint56_max = type(uint56).max; + require(uint56_max == 2**56-1); + + uint64 uint64_max = type(uint64).max; + require(uint64_max == 2**64-1); + + return true; + } + + function uintMaxB() public pure returns (bool) { + + uint72 uint72_max = type(uint72).max; + require(uint72_max == 2**72-1); + + uint80 uint80_max = type(uint80).max; + require(uint80_max == 2**80-1); + + uint88 uint88_max = type(uint88).max; + require(uint88_max == 2**88-1); + + uint96 uint96_max = type(uint96).max; + require(uint96_max == 2**96-1); + + uint104 uint104_max = type(uint104).max; + require(uint104_max == 2**104-1); + + uint112 uint112_max = type(uint112).max; + require(uint112_max == 2**112-1); + + uint120 uint120_max = type(uint120).max; + require(uint120_max == 2**120-1); + + uint128 uint128_max = type(uint128).max; + require(uint128_max == 2**128-1); + + return true; + } + + function uintMaxC() public pure returns (bool) { + + uint136 uint136_max = type(uint136).max; + require(uint136_max == 2**136-1); + + uint144 uint144_max = type(uint144).max; + require(uint144_max == 2**144-1); + + uint152 uint152_max = type(uint152).max; + require(uint152_max == 2**152-1); + + uint160 uint160_max = type(uint160).max; + require(uint160_max == 2**160-1); + + uint168 uint168_max = type(uint168).max; + require(uint168_max == 2**168-1); + + uint176 uint176_max = type(uint176).max; + require(uint176_max == 2**176-1); + + uint184 uint184_max = type(uint184).max; + require(uint184_max == 2**184-1); + + uint192 uint192_max = type(uint192).max; + require(uint192_max == 2**192-1); + + return true; + } + + function uintMaxD() public pure returns(bool) { + uint200 uint200_max = type(uint200).max; + require(uint200_max == 2**200-1); + + uint208 uint208_max = type(uint208).max; + require(uint208_max == 2**208-1); + + uint216 uint216_max = type(uint216).max; + require(uint216_max == 2**216-1); + + uint224 uint224_max = type(uint224).max; + require(uint224_max == 2**224-1); + + uint232 uint232_max = type(uint232).max; + require(uint232_max == 2**232-1); + + uint240 uint240_max = type(uint240).max; + require(uint240_max == 2**240-1); + + uint248 uint248_max = type(uint248).max; + require(uint248_max == 2**248-1); + + uint256 uint256_max = type(uint256).max; + require(uint256_max == 2**256-1); + + return true; + } +} +// ---- +// uintMinA() -> true +// uintMinB() -> true +// uintMinC() -> true +// uintMinD() -> true +// uintMaxA() -> true +// uintMaxB() -> true +// uintMaxC() -> true +// uintMaxD() -> true diff --git a/examples/test/semanticTests/integer_uint/uint_standard_input.json b/examples/test/semanticTests/integer_uint/uint_standard_input.json new file mode 100644 index 00000000..7f4b3be4 --- /dev/null +++ b/examples/test/semanticTests/integer_uint/uint_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "uint.sol": { + "content": "contract test {\n\n\tfunction uintMinA() public pure returns(bool) {\n\n\t\tuint8 uint8_min = type(uint8).min;\n\t\trequire(uint8_min == 0);\n\n\t\tuint16 uint16_min = type(uint16).min;\n\t\trequire(uint16_min == 0);\n\n\t\tuint24 uint24_min = type(uint24).min;\n\t\trequire(uint24_min == 0);\n\n\t\tuint32 uint32_min = type(uint32).min;\n\t\trequire(uint32_min == 0);\n\n\t\tuint40 uint40_min = type(uint40).min;\n\t\trequire(uint40_min == 0);\n\n\t\tuint48 uint48_min = type(uint48).min;\n\t\trequire(uint48_min == 0);\n\n\t\tuint56 uint56_min = type(uint56).min;\n\t\trequire(uint56_min == 0);\n\n\t\tuint64 uint64_min = type(uint64).min;\n\t\trequire(uint64_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinB() public pure returns(bool) {\n\n\t\tuint72 uint72_min = type(uint72).min;\n\t\trequire(uint72_min == 0);\n\n\t\tuint80 uint80_min = type(uint80).min;\n\t\trequire(uint80_min == 0);\n\n\t\tuint88 uint88_min = type(uint88).min;\n\t\trequire(uint88_min == 0);\n\n\t\tuint96 uint96_min = type(uint96).min;\n\t\trequire(uint96_min == 0);\n\n\t\tuint104 uint104_min = type(uint104).min;\n\t\trequire(uint104_min == 0);\n\n\t\tuint112 uint112_min = type(uint112).min;\n\t\trequire(uint112_min == 0);\n\n\t\tuint120 uint120_min = type(uint120).min;\n\t\trequire(uint120_min == 0);\n\n\t\tuint128 uint128_min = type(uint128).min;\n\t\trequire(uint128_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinC() public pure returns(bool) {\n\n\t\tuint136 uint136_min = type(uint136).min;\n\t\trequire(uint136_min == 0);\n\n\t\tuint144 uint144_min = type(uint144).min;\n\t\trequire(uint144_min == 0);\n\n\t\tuint152 uint152_min = type(uint152).min;\n\t\trequire(uint152_min == 0);\n\n\t\tuint160 uint160_min = type(uint160).min;\n\t\trequire(uint160_min == 0);\n\n\t\tuint168 uint168_min = type(uint168).min;\n\t\trequire(uint168_min == 0);\n\n\t\tuint176 uint176_min = type(uint176).min;\n\t\trequire(uint176_min == 0);\n\n\t\tuint184 uint184_min = type(uint184).min;\n\t\trequire(uint184_min == 0);\n\n\t\tuint192 uint192_min = type(uint192).min;\n\t\trequire(uint192_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMinD() public pure returns(bool) {\n\n\t\tuint200 uint200_min = type(uint200).min;\n\t\trequire(uint200_min == 0);\n\n\t\tuint208 uint208_min = type(uint208).min;\n\t\trequire(uint208_min == 0);\n\n\t\tuint216 uint216_min = type(uint216).min;\n\t\trequire(uint216_min == 0);\n\n\t\tuint224 uint224_min = type(uint224).min;\n\t\trequire(uint224_min == 0);\n\n\t\tuint232 uint232_min = type(uint232).min;\n\t\trequire(uint232_min == 0);\n\n\t\tuint240 uint240_min = type(uint240).min;\n\t\trequire(uint240_min == 0);\n\n\t\tuint248 uint248_min = type(uint248).min;\n\t\trequire(uint248_min == 0);\n\n\t\tuint256 uint256_min = type(uint256).min;\n\t\trequire(uint256_min == 0);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxA() public pure returns (bool) {\n\n\t\tuint8 uint8_max = type(uint8).max;\n\t\trequire(uint8_max == 2**8-1);\n\n\t\tuint16 uint16_max = type(uint16).max;\n\t\trequire(uint16_max == 2**16-1);\n\n\t\tuint24 uint24_max = type(uint24).max;\n\t\trequire(uint24_max == 2**24-1);\n\n\t\tuint32 uint32_max = type(uint32).max;\n\t\trequire(uint32_max == 2**32-1);\n\n\t\tuint40 uint40_max = type(uint40).max;\n\t\trequire(uint40_max == 2**40-1);\n\n\t\tuint48 uint48_max = type(uint48).max;\n\t\trequire(uint48_max == 2**48-1);\n\n\t\tuint56 uint56_max = type(uint56).max;\n\t\trequire(uint56_max == 2**56-1);\n\n\t\tuint64 uint64_max = type(uint64).max;\n\t\trequire(uint64_max == 2**64-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxB() public pure returns (bool) {\n\n\t\tuint72 uint72_max = type(uint72).max;\n\t\trequire(uint72_max == 2**72-1);\n\n\t\tuint80 uint80_max = type(uint80).max;\n\t\trequire(uint80_max == 2**80-1);\n\n\t\tuint88 uint88_max = type(uint88).max;\n\t\trequire(uint88_max == 2**88-1);\n\n\t\tuint96 uint96_max = type(uint96).max;\n\t\trequire(uint96_max == 2**96-1);\n\n\t\tuint104 uint104_max = type(uint104).max;\n\t\trequire(uint104_max == 2**104-1);\n\n\t\tuint112 uint112_max = type(uint112).max;\n\t\trequire(uint112_max == 2**112-1);\n\n\t\tuint120 uint120_max = type(uint120).max;\n\t\trequire(uint120_max == 2**120-1);\n\n\t\tuint128 uint128_max = type(uint128).max;\n\t\trequire(uint128_max == 2**128-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxC() public pure returns (bool) {\n\n\t\tuint136 uint136_max = type(uint136).max;\n\t\trequire(uint136_max == 2**136-1);\n\n\t\tuint144 uint144_max = type(uint144).max;\n\t\trequire(uint144_max == 2**144-1);\n\n\t\tuint152 uint152_max = type(uint152).max;\n\t\trequire(uint152_max == 2**152-1);\n\n\t\tuint160 uint160_max = type(uint160).max;\n\t\trequire(uint160_max == 2**160-1);\n\n\t\tuint168 uint168_max = type(uint168).max;\n\t\trequire(uint168_max == 2**168-1);\n\n\t\tuint176 uint176_max = type(uint176).max;\n\t\trequire(uint176_max == 2**176-1);\n\n\t\tuint184 uint184_max = type(uint184).max;\n\t\trequire(uint184_max == 2**184-1);\n\n\t\tuint192 uint192_max = type(uint192).max;\n\t\trequire(uint192_max == 2**192-1);\n\n\t\treturn true;\n\t}\n\n\tfunction uintMaxD() public pure returns(bool) {\n\t\tuint200 uint200_max = type(uint200).max;\n\t\trequire(uint200_max == 2**200-1);\n\n\t\tuint208 uint208_max = type(uint208).max;\n\t\trequire(uint208_max == 2**208-1);\n\n\t\tuint216 uint216_max = type(uint216).max;\n\t\trequire(uint216_max == 2**216-1);\n\n\t\tuint224 uint224_max = type(uint224).max;\n\t\trequire(uint224_max == 2**224-1);\n\n\t\tuint232 uint232_max = type(uint232).max;\n\t\trequire(uint232_max == 2**232-1);\n\n\t\tuint240 uint240_max = type(uint240).max;\n\t\trequire(uint240_max == 2**240-1);\n\n\t\tuint248 uint248_max = type(uint248).max;\n\t\trequire(uint248_max == 2**248-1);\n\n\t\tuint256 uint256_max = type(uint256).max;\n\t\trequire(uint256_max == 2**256-1);\n\n\t\treturn true;\n\t}\n}\n// ----\n// uintMinA() -> true\n// uintMinB() -> true\n// uintMinC() -> true\n// uintMinD() -> true\n// uintMaxA() -> true\n// uintMaxB() -> true\n// uintMaxC() -> true\n// uintMaxD() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interfaceID_homer/homer.sol b/examples/test/semanticTests/interfaceID_homer/homer.sol new file mode 100644 index 00000000..fbe6293d --- /dev/null +++ b/examples/test/semanticTests/interfaceID_homer/homer.sol @@ -0,0 +1,35 @@ +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + +interface Simpson { + function is2D() external returns (bool); + function skinColor() external returns (string memory); +} + +contract Homer is ERC165, Simpson { + function supportsInterface(bytes4 interfaceID) external view override returns (bool) { + return + interfaceID == this.supportsInterface.selector || // ERC165 + interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson + } + + function is2D() external override returns (bool) { + return true; + } + + function skinColor() external override returns (string memory) { + return "yellow"; + } +} +// ---- +// supportsInterface(bytes4): left(0x01ffc9a0) -> false +// supportsInterface(bytes4): left(0x01ffc9a7) -> true +// supportsInterface(bytes4): left(0x73b6b492) -> true +// supportsInterface(bytes4): left(0x70b6b492) -> false diff --git a/examples/test/semanticTests/interfaceID_homer/homer_standard_input.json b/examples/test/semanticTests/interfaceID_homer/homer_standard_input.json new file mode 100644 index 00000000..732c0f9e --- /dev/null +++ b/examples/test/semanticTests/interfaceID_homer/homer_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "interfaceId_events.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n event Event();\n function hello() external pure;\n function world(int) external pure;\n}\n\ncontract Test {\n bytes4 public hello_world = type(HelloWorld).interfaceId;\n bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n" + }, + "lisa.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "lisa_interfaceId.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[type(Simpson).interfaceId] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "homer.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return\n interfaceID == this.supportsInterface.selector || // ERC165\n interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId.sol b/examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId.sol new file mode 100644 index 00000000..c66169cd --- /dev/null +++ b/examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId.sol @@ -0,0 +1,35 @@ +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + +interface Simpson { + function is2D() external returns (bool); + function skinColor() external returns (string memory); +} + +contract Homer is ERC165, Simpson { + function supportsInterface(bytes4 interfaceID) external view override returns (bool) { + return + interfaceID == type(ERC165).interfaceId || + interfaceID == type(Simpson).interfaceId; + } + + function is2D() external override returns (bool) { + return true; + } + + function skinColor() external override returns (string memory) { + return "yellow"; + } +} +// ---- +// supportsInterface(bytes4): left(0x01ffc9a0) -> false +// supportsInterface(bytes4): left(0x01ffc9a7) -> true +// supportsInterface(bytes4): left(0x73b6b492) -> true +// supportsInterface(bytes4): left(0x70b6b492) -> false diff --git a/examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId_standard_input.json b/examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId_standard_input.json new file mode 100644 index 00000000..477b3782 --- /dev/null +++ b/examples/test/semanticTests/interfaceID_homer_interfaceId/homer_interfaceId_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "interfaceId_events.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n event Event();\n function hello() external pure;\n function world(int) external pure;\n}\n\ncontract Test {\n bytes4 public hello_world = type(HelloWorld).interfaceId;\n bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n" + }, + "lisa.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "lisa_interfaceId.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[type(Simpson).interfaceId] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "homer.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return\n interfaceID == this.supportsInterface.selector || // ERC165\n interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "homer_interfaceId.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return\n interfaceID == type(ERC165).interfaceId ||\n interfaceID == type(Simpson).interfaceId;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events.sol b/examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events.sol new file mode 100644 index 00000000..9bbf11be --- /dev/null +++ b/examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events.sol @@ -0,0 +1,18 @@ +interface HelloWorld { + function hello() external pure; + function world(int) external pure; +} + +interface HelloWorldWithEvent { + event Event(); + function hello() external pure; + function world(int) external pure; +} + +contract Test { + bytes4 public hello_world = type(HelloWorld).interfaceId; + bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId; +} +// ---- +// hello_world() -> left(0xc6be8b58) +// hello_world_with_event() -> left(0xc6be8b58) diff --git a/examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events_standard_input.json b/examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events_standard_input.json new file mode 100644 index 00000000..2ecb831d --- /dev/null +++ b/examples/test/semanticTests/interfaceID_interfaceId_events/interfaceId_events_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "interfaceId_events.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n event Event();\n function hello() external pure;\n function world(int) external pure;\n}\n\ncontract Test {\n bytes4 public hello_world = type(HelloWorld).interfaceId;\n bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interfaceID_interfaces/interfaces.sol b/examples/test/semanticTests/interfaceID_interfaces/interfaces.sol new file mode 100644 index 00000000..f66d859e --- /dev/null +++ b/examples/test/semanticTests/interfaceID_interfaces/interfaces.sol @@ -0,0 +1,61 @@ +interface HelloWorld { + function hello() external pure; + function world(int) external pure; +} + +interface HelloWorldDerived is HelloWorld { + function other() external pure; +} + +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + +contract Test { + bytes4 public ghello_world_interfaceId = type(HelloWorld).interfaceId; + bytes4 public ERC165_interfaceId = type(ERC165).interfaceId; + + function hello() public pure returns (bytes4 data){ + HelloWorld i; + return i.hello.selector; + } + + function world() public pure returns (bytes4 data){ + HelloWorld i; + return i.world.selector; + } + + function hello_world() public pure returns (bytes4 data){ + // HelloWorld i; + // return i.hello.selector ^ i.world.selector; // = 0xc6be8b58 + return 0xc6be8b58; + } + + function hello_world_interfaceId() public pure returns (bytes4 data){ + return type(HelloWorld).interfaceId; + } + + function other() public pure returns (bytes4 data){ + HelloWorldDerived i; + return i.other.selector; + } + + function hello_world_derived_interfaceId() public pure returns (bytes4 data){ + return type(HelloWorldDerived).interfaceId; + } +} +// ---- +// hello() -> left(0x19ff1d21) +// world() -> left(0xdf419679) +// ERC165_interfaceId() -> left(0x01ffc9a7) +// hello_world() -> left(0xc6be8b58) +// hello_world_interfaceId() -> left(0xc6be8b58) +// ghello_world_interfaceId() -> left(0xc6be8b58) +// other() -> left(0x85295877) +// hello_world_derived_interfaceId() -> left(0x85295877) diff --git a/examples/test/semanticTests/interfaceID_interfaces/interfaces_standard_input.json b/examples/test/semanticTests/interfaceID_interfaces/interfaces_standard_input.json new file mode 100644 index 00000000..a1fed6d7 --- /dev/null +++ b/examples/test/semanticTests/interfaceID_interfaces/interfaces_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "interfaceId_events.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n event Event();\n function hello() external pure;\n function world(int) external pure;\n}\n\ncontract Test {\n bytes4 public hello_world = type(HelloWorld).interfaceId;\n bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n" + }, + "lisa.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "lisa_interfaceId.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[type(Simpson).interfaceId] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "homer.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return\n interfaceID == this.supportsInterface.selector || // ERC165\n interfaceID == this.is2D.selector ^ this.skinColor.selector; // Simpson\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "homer_interfaceId.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Homer is ERC165, Simpson {\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return\n interfaceID == type(ERC165).interfaceId ||\n interfaceID == type(Simpson).interfaceId;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "interfaces.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldDerived is HelloWorld {\n function other() external pure;\n}\n\ninterface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\ncontract Test {\n bytes4 public ghello_world_interfaceId = type(HelloWorld).interfaceId;\n bytes4 public ERC165_interfaceId = type(ERC165).interfaceId;\n\n function hello() public pure returns (bytes4 data){\n HelloWorld i;\n return i.hello.selector;\n }\n\n function world() public pure returns (bytes4 data){\n HelloWorld i;\n return i.world.selector;\n }\n\n function hello_world() public pure returns (bytes4 data){\n // HelloWorld i;\n // return i.hello.selector ^ i.world.selector; // = 0xc6be8b58\n return 0xc6be8b58;\n }\n\n function hello_world_interfaceId() public pure returns (bytes4 data){\n return type(HelloWorld).interfaceId;\n }\n\n function other() public pure returns (bytes4 data){\n HelloWorldDerived i;\n return i.other.selector;\n }\n\n function hello_world_derived_interfaceId() public pure returns (bytes4 data){\n return type(HelloWorldDerived).interfaceId;\n }\n}\n// ----\n// hello() -> left(0x19ff1d21)\n// world() -> left(0xdf419679)\n// ERC165_interfaceId() -> left(0x01ffc9a7)\n// hello_world() -> left(0xc6be8b58)\n// hello_world_interfaceId() -> left(0xc6be8b58)\n// ghello_world_interfaceId() -> left(0xc6be8b58)\n// other() -> left(0x85295877)\n// hello_world_derived_interfaceId() -> left(0x85295877)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interfaceID_lisa/lisa.sol b/examples/test/semanticTests/interfaceID_lisa/lisa.sol new file mode 100644 index 00000000..722502d8 --- /dev/null +++ b/examples/test/semanticTests/interfaceID_lisa/lisa.sol @@ -0,0 +1,46 @@ +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + +abstract contract ERC165MappingImplementation is ERC165 { + /// @dev You must not set element 0xffffffff to true + mapping(bytes4 => bool) internal supportedInterfaces; + + constructor() { + supportedInterfaces[this.supportsInterface.selector] = true; + } + + function supportsInterface(bytes4 interfaceID) external view override returns (bool) { + return supportedInterfaces[interfaceID]; + } +} + +interface Simpson { + function is2D() external returns (bool); + function skinColor() external returns (string memory); +} + +contract Lisa is ERC165MappingImplementation, Simpson { + constructor() { + supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true; + } + + function is2D() external override returns (bool) { + return true; + } + + function skinColor() external override returns (string memory) { + return "yellow"; + } +} +// ---- +// supportsInterface(bytes4): left(0x01ffc9a0) -> false +// supportsInterface(bytes4): left(0x01ffc9a7) -> true +// supportsInterface(bytes4): left(0x73b6b492) -> true +// supportsInterface(bytes4): left(0x70b6b492) -> false diff --git a/examples/test/semanticTests/interfaceID_lisa/lisa_standard_input.json b/examples/test/semanticTests/interfaceID_lisa/lisa_standard_input.json new file mode 100644 index 00000000..5922683a --- /dev/null +++ b/examples/test/semanticTests/interfaceID_lisa/lisa_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "interfaceId_events.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n event Event();\n function hello() external pure;\n function world(int) external pure;\n}\n\ncontract Test {\n bytes4 public hello_world = type(HelloWorld).interfaceId;\n bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n" + }, + "lisa.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId.sol b/examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId.sol new file mode 100644 index 00000000..457ac885 --- /dev/null +++ b/examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId.sol @@ -0,0 +1,46 @@ +interface ERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} + +abstract contract ERC165MappingImplementation is ERC165 { + /// @dev You must not set element 0xffffffff to true + mapping(bytes4 => bool) internal supportedInterfaces; + + constructor() { + supportedInterfaces[this.supportsInterface.selector] = true; + } + + function supportsInterface(bytes4 interfaceID) external view override returns (bool) { + return supportedInterfaces[interfaceID]; + } +} + +interface Simpson { + function is2D() external returns (bool); + function skinColor() external returns (string memory); +} + +contract Lisa is ERC165MappingImplementation, Simpson { + constructor() { + supportedInterfaces[type(Simpson).interfaceId] = true; + } + + function is2D() external override returns (bool) { + return true; + } + + function skinColor() external override returns (string memory) { + return "yellow"; + } +} +// ---- +// supportsInterface(bytes4): left(0x01ffc9a0) -> false +// supportsInterface(bytes4): left(0x01ffc9a7) -> true +// supportsInterface(bytes4): left(0x73b6b492) -> true +// supportsInterface(bytes4): left(0x70b6b492) -> false diff --git a/examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId_standard_input.json b/examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId_standard_input.json new file mode 100644 index 00000000..eb81398a --- /dev/null +++ b/examples/test/semanticTests/interfaceID_lisa_interfaceId/lisa_interfaceId_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "interfaceId_events.sol": { + "content": "interface HelloWorld {\n function hello() external pure;\n function world(int) external pure;\n}\n\ninterface HelloWorldWithEvent {\n event Event();\n function hello() external pure;\n function world(int) external pure;\n}\n\ncontract Test {\n bytes4 public hello_world = type(HelloWorld).interfaceId;\n bytes4 public hello_world_with_event = type(HelloWorldWithEvent).interfaceId;\n}\n// ----\n// hello_world() -> left(0xc6be8b58)\n// hello_world_with_event() -> left(0xc6be8b58)\n" + }, + "lisa.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[this.is2D.selector ^ this.skinColor.selector] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + }, + "lisa_interfaceId.sol": { + "content": "interface ERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n\nabstract contract ERC165MappingImplementation is ERC165 {\n /// @dev You must not set element 0xffffffff to true\n mapping(bytes4 => bool) internal supportedInterfaces;\n\n constructor() {\n supportedInterfaces[this.supportsInterface.selector] = true;\n }\n\n function supportsInterface(bytes4 interfaceID) external view override returns (bool) {\n return supportedInterfaces[interfaceID];\n }\n}\n\ninterface Simpson {\n function is2D() external returns (bool);\n function skinColor() external returns (string memory);\n}\n\ncontract Lisa is ERC165MappingImplementation, Simpson {\n constructor() {\n supportedInterfaces[type(Simpson).interfaceId] = true;\n }\n\n function is2D() external override returns (bool) {\n return true;\n }\n\n function skinColor() external override returns (string memory) {\n return \"yellow\";\n }\n}\n// ----\n// supportsInterface(bytes4): left(0x01ffc9a0) -> false\n// supportsInterface(bytes4): left(0x01ffc9a7) -> true\n// supportsInterface(bytes4): left(0x73b6b492) -> true\n// supportsInterface(bytes4): left(0x70b6b492) -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions.sol b/examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions.sol new file mode 100644 index 00000000..62e1e4fb --- /dev/null +++ b/examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions.sol @@ -0,0 +1,43 @@ +interface Parent { + function parentFun() external returns (uint256); +} + +interface SubA is Parent { + function subAFun() external returns (uint256); +} + +interface SubB is Parent { + function subBFun() external returns (uint256); +} + +contract Impl is SubA, SubB { + function parentFun() override external returns (uint256) { return 1; } + function subAFun() override external returns (uint256) { return 2; } + function subBFun() override external returns (uint256) { return 3; } +} + +contract C { + function convertParent() public returns (uint256) { + Parent p = new Impl(); + return p.parentFun(); + } + + function convertSubA() public returns (uint256, uint256) { + SubA sa = new Impl(); + return (sa.parentFun(), sa.subAFun()); + } + + function convertSubB() public returns (uint256, uint256) { + SubB sb = new Impl(); + return (sb.parentFun(), sb.subBFun()); + } +} +// ---- +// convertParent() -> 1 +// gas irOptimized: 85524 +// convertSubA() -> 1, 2 +// gas irOptimized: 86155 +// gas legacy: 99047 +// convertSubB() -> 1, 3 +// gas irOptimized: 86098 +// gas legacy: 98981 diff --git a/examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions_standard_input.json b/examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions_standard_input.json new file mode 100644 index 00000000..74469c30 --- /dev/null +++ b/examples/test/semanticTests/interface_inheritance_conversions_1/interface_inheritance_conversions_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + }, + "c99_scoping_activation.sol": { + "content": "contract test {\n function f() pure public returns (uint) {\n uint x = 7;\n {\n x = 3; // This should still assign to the outer variable\n uint x;\n x = 4; // This should assign to the new one\n }\n return x;\n }\n function g() pure public returns (uint x) {\n x = 7;\n {\n x = 3;\n uint x;\n return x; // This returns the new variable, i.e. 0\n }\n }\n function h() pure public returns (uint x, uint a, uint b) {\n x = 7;\n {\n x = 3;\n a = x; // This should read from the outer\n uint x = 4;\n b = x;\n }\n }\n function i() pure public returns (uint x, uint a) {\n x = 7;\n {\n x = 3;\n uint x = x; // This should read from the outer and assign to the inner\n a = x;\n }\n }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n" + }, + "empty_contract.sol": { + "content": "contract test {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// i_am_not_there() -> FAILURE\n" + }, + "dirty_calldata_bytes.sol": { + "content": "contract C {\n function f(bytes calldata b) public returns (bool correct) {\n bytes1 a = b[3];\n uint r;\n assembly {\n r := a\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f(bytes): 0x20, 0x04, \"dead\" -> true\n" + }, + "state_var_initialization.sol": { + "content": "contract C {\n uint public i = 1;\n uint public k = 2;\n\n constructor() {\n i = i + i;\n k = k - i;\n }\n}\n// ----\n// i() -> 2\n// k() -> 0\n" + }, + "interface_inheritance_conversions.sol": { + "content": "interface Parent {\n function parentFun() external returns (uint256);\n}\n\ninterface SubA is Parent {\n function subAFun() external returns (uint256);\n}\n\ninterface SubB is Parent {\n function subBFun() external returns (uint256);\n}\n\ncontract Impl is SubA, SubB {\n function parentFun() override external returns (uint256) { return 1; }\n function subAFun() override external returns (uint256) { return 2; }\n function subBFun() override external returns (uint256) { return 3; }\n}\n\ncontract C {\n function convertParent() public returns (uint256) {\n Parent p = new Impl();\n return p.parentFun();\n }\n\n function convertSubA() public returns (uint256, uint256) {\n SubA sa = new Impl();\n return (sa.parentFun(), sa.subAFun());\n }\n\n function convertSubB() public returns (uint256, uint256) {\n SubB sb = new Impl();\n return (sb.parentFun(), sb.subBFun());\n }\n}\n// ----\n// convertParent() -> 1\n// gas irOptimized: 85524\n// convertSubA() -> 1, 2\n// gas irOptimized: 86155\n// gas legacy: 99047\n// convertSubB() -> 1, 3\n// gas irOptimized: 86098\n// gas legacy: 98981\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting.sol b/examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting.sol new file mode 100644 index 00000000..9380dc01 --- /dev/null +++ b/examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting.sol @@ -0,0 +1,13 @@ +contract C { + function f() public returns (uint[5] memory) { + uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222]; + return a; + } + function g() public returns (uint[5] memory) { + uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e]; + return a; + } +} +// ---- +// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222 +// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222 diff --git a/examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting_standard_input.json b/examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting_standard_input.json new file mode 100644 index 00000000..3b6a5452 --- /dev/null +++ b/examples/test/semanticTests/isoltestFormatting_1/isoltestFormatting_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_account/account.sol b/examples/test/semanticTests/isoltestTesting_account/account.sol new file mode 100644 index 00000000..7b6c55b1 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_account/account.sol @@ -0,0 +1,46 @@ +contract AccountBuiltinTest { + function who_am_i() public returns (address result) { + result = msg.sender; + } +} +// ---- +// constructor() +// account: 0 -> 0x1212121212121212121212121212120000000012 +// who_am_i() -> 0x1212121212121212121212121212120000000012 +// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376 +// account: 1 -> 0x1212121212121212121212121212120000001012 +// who_am_i() -> 0x1212121212121212121212121212120000001012 +// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376 +// account: 2 -> 0x1212121212121212121212121212120000002012 +// who_am_i() -> 0x1212121212121212121212121212120000002012 +// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376 +// account: 3 -> 0x1212121212121212121212121212120000003012 +// who_am_i() -> 0x1212121212121212121212121212120000003012 +// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376 +// account: 4 -> 0x1212121212121212121212121212120000004012 +// who_am_i() -> 0x1212121212121212121212121212120000004012 +// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376 +// account: 5 -> 0x1212121212121212121212121212120000005012 +// who_am_i() -> 0x1212121212121212121212121212120000005012 +// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376 +// account: 6 -> 0x1212121212121212121212121212120000006012 +// who_am_i() -> 0x1212121212121212121212121212120000006012 +// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376 +// account: 7 -> 0x1212121212121212121212121212120000007012 +// who_am_i() -> 0x1212121212121212121212121212120000007012 +// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376 +// account: 8 -> 0x1212121212121212121212121212120000008012 +// who_am_i() -> 0x1212121212121212121212121212120000008012 +// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376 +// account: 9 -> 0x1212121212121212121212121212120000009012 +// who_am_i() -> 0x1212121212121212121212121212120000009012 +// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376 +// account: 10 -> 0x121212121212121212121212121212000000a012 +// who_am_i() -> 0x121212121212121212121212121212000000a012 +// balance: 0x121212121212121212121212121212000000a012 -> 0 +// account: 11 -> 0x121212121212121212121212121212000000b012 +// who_am_i() -> 0x121212121212121212121212121212000000b012 +// balance: 0x121212121212121212121212121212000000b012 -> 0 +// account: 12 -> 0x121212121212121212121212121212000000c012 +// who_am_i() -> 0x121212121212121212121212121212000000c012 +// balance: 0x121212121212121212121212121212000000c012 -> 0 diff --git a/examples/test/semanticTests/isoltestTesting_account/account_standard_input.json b/examples/test/semanticTests/isoltestTesting_account/account_standard_input.json new file mode 100644 index 00000000..8ed3a58d --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_account/account_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract.sol b/examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract.sol new file mode 100644 index 00000000..1240a825 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract.sol @@ -0,0 +1,30 @@ +contract Other { + constructor() payable { + } + function getAddress() public returns (address) { + return address(this); + } +} +contract ClientReceipt { + Other other; + constructor() payable { + other = new Other{value:500}(); + } + function getAddress() public returns (address) { + return other.getAddress(); + } +} +// ---- +// constructor(), 2000 wei -> +// gas irOptimized: 114353 +// gas irOptimized code: 58800 +// gas legacy: 118617 +// gas legacy code: 111400 +// gas legacyOptimized: 114067 +// gas legacyOptimized code: 59800 +// balance -> 1500 +// gas irOptimized: 191881 +// gas legacy: 235167 +// gas legacyOptimized: 180756 +// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a +// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500 diff --git a/examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract_standard_input.json b/examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract_standard_input.json new file mode 100644 index 00000000..7a4141c5 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_other_contract/balance_other_contract_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + }, + "balance_without_balance.sol": { + "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n" + }, + "balance_other_contract.sol": { + "content": "contract Other {\n constructor() payable {\n }\n function getAddress() public returns (address) {\n return address(this);\n }\n}\ncontract ClientReceipt {\n Other other;\n constructor() payable {\n other = new Other{value:500}();\n }\n function getAddress() public returns (address) {\n return other.getAddress();\n }\n}\n// ----\n// constructor(), 2000 wei ->\n// gas irOptimized: 114353\n// gas irOptimized code: 58800\n// gas legacy: 118617\n// gas legacy code: 111400\n// gas legacyOptimized: 114067\n// gas legacyOptimized code: 59800\n// balance -> 1500\n// gas irOptimized: 191881\n// gas legacy: 235167\n// gas legacyOptimized: 180756\n// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance.sol b/examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance.sol new file mode 100644 index 00000000..3fd67d57 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance.sol @@ -0,0 +1,6 @@ +contract ClientReceipt { + constructor() payable {} +} +// ---- +// constructor(), 1000 wei -> +// balance -> 1000 diff --git a/examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance_standard_input.json b/examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance_standard_input.json new file mode 100644 index 00000000..e9270873 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_with_balance/balance_with_balance_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2.sol b/examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2.sol new file mode 100644 index 00000000..4b940fe8 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2.sol @@ -0,0 +1,6 @@ +contract ClientReceipt { + constructor() payable {} +} +// ---- +// constructor(), 1 ether -> +// balance -> 1000000000000000000 diff --git a/examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2_standard_input.json b/examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2_standard_input.json new file mode 100644 index 00000000..cc81a30b --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_with_balance2/balance_with_balance2_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + }, + "balance_without_balance.sol": { + "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n" + }, + "balance_other_contract.sol": { + "content": "contract Other {\n constructor() payable {\n }\n function getAddress() public returns (address) {\n return address(this);\n }\n}\ncontract ClientReceipt {\n Other other;\n constructor() payable {\n other = new Other{value:500}();\n }\n function getAddress() public returns (address) {\n return other.getAddress();\n }\n}\n// ----\n// constructor(), 2000 wei ->\n// gas irOptimized: 114353\n// gas irOptimized code: 58800\n// gas legacy: 118617\n// gas legacy code: 111400\n// gas legacyOptimized: 114067\n// gas legacyOptimized code: 59800\n// balance -> 1500\n// gas irOptimized: 191881\n// gas legacy: 235167\n// gas legacyOptimized: 180756\n// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500\n" + }, + "format_raw_string_with_control_chars.sol": { + "content": "contract C {\n function f(string memory s) external pure returns (string memory) {\n return s;\n }\n}\n// NOTE: The test is here to illustrate the problem with formatting control chars in strings in\n// test expectations but unfortunately it can only be triggered manually. It does not test anything\n// unless you introduce a difference in expectations to force isoltest to reformat them.\n// ----\n// f(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" # Input/Output: \"\ud83d\ude03\ud83d\ude03\ud83d\ude03\ud83d\ude03\" #\n" + }, + "balance_with_balance2.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1 ether ->\n// balance -> 1000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance.sol b/examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance.sol new file mode 100644 index 00000000..222fba4e --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance.sol @@ -0,0 +1,5 @@ +contract ClientReceipt { +} +// ---- +// balance -> 0 +// balance: 0x0000000000000000000000000000000000000000 -> 0 diff --git a/examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance_standard_input.json b/examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance_standard_input.json new file mode 100644 index 00000000..a2a81b1a --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_balance_without_balance/balance_without_balance_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + }, + "balance_without_balance.sol": { + "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_builtins/builtins.sol b/examples/test/semanticTests/isoltestTesting_builtins/builtins.sol new file mode 100644 index 00000000..e8faa0cc --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_builtins/builtins.sol @@ -0,0 +1,4 @@ +contract SmokeTest { +} +// ---- +// isoltest_builtin_test -> 0x1234 diff --git a/examples/test/semanticTests/isoltestTesting_builtins/builtins_standard_input.json b/examples/test/semanticTests/isoltestTesting_builtins/builtins_standard_input.json new file mode 100644 index 00000000..dcfe72e5 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_builtins/builtins_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + }, + "balance_without_balance.sol": { + "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n" + }, + "balance_other_contract.sol": { + "content": "contract Other {\n constructor() payable {\n }\n function getAddress() public returns (address) {\n return address(this);\n }\n}\ncontract ClientReceipt {\n Other other;\n constructor() payable {\n other = new Other{value:500}();\n }\n function getAddress() public returns (address) {\n return other.getAddress();\n }\n}\n// ----\n// constructor(), 2000 wei ->\n// gas irOptimized: 114353\n// gas irOptimized code: 58800\n// gas legacy: 118617\n// gas legacy code: 111400\n// gas legacyOptimized: 114067\n// gas legacyOptimized code: 59800\n// balance -> 1500\n// gas irOptimized: 191881\n// gas legacy: 235167\n// gas legacyOptimized: 180756\n// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500\n" + }, + "format_raw_string_with_control_chars.sol": { + "content": "contract C {\n function f(string memory s) external pure returns (string memory) {\n return s;\n }\n}\n// NOTE: The test is here to illustrate the problem with formatting control chars in strings in\n// test expectations but unfortunately it can only be triggered manually. It does not test anything\n// unless you introduce a difference in expectations to force isoltest to reformat them.\n// ----\n// f(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" # Input/Output: \"\ud83d\ude03\ud83d\ude03\ud83d\ude03\ud83d\ude03\" #\n" + }, + "balance_with_balance2.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1 ether ->\n// balance -> 1000000000000000000\n" + }, + "builtins.sol": { + "content": "contract SmokeTest {\n}\n// ----\n// isoltest_builtin_test -> 0x1234\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_effects/effects.sol b/examples/test/semanticTests/isoltestTesting_effects/effects.sol new file mode 100644 index 00000000..c9ab6c3e --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_effects/effects.sol @@ -0,0 +1,13 @@ +contract SmokeTest { +} +// ---- +// isoltest_side_effects_test -> 0 +// isoltest_side_effects_test: 0x1234 -> 0x1234 +// ~ 0000000000000000000000000000000000000000000000000000000000001234 +// isoltest_side_effects_test: 0x1234, 0x2345 # comment # -> 0x1234, 0x2345 +// ~ 0000000000000000000000000000000000000000000000000000000000001234 +// ~ 0000000000000000000000000000000000000000000000000000000000002345 +// isoltest_side_effects_test: 0x1234, 0x2345, 0x3456 -> 0x1234, 0x2345, 0x3456 # comment # +// ~ 0000000000000000000000000000000000000000000000000000000000001234 +// ~ 0000000000000000000000000000000000000000000000000000000000002345 +// ~ 0000000000000000000000000000000000000000000000000000000000003456 diff --git a/examples/test/semanticTests/isoltestTesting_effects/effects_standard_input.json b/examples/test/semanticTests/isoltestTesting_effects/effects_standard_input.json new file mode 100644 index 00000000..584c4ec0 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_effects/effects_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + }, + "balance_without_balance.sol": { + "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n" + }, + "balance_other_contract.sol": { + "content": "contract Other {\n constructor() payable {\n }\n function getAddress() public returns (address) {\n return address(this);\n }\n}\ncontract ClientReceipt {\n Other other;\n constructor() payable {\n other = new Other{value:500}();\n }\n function getAddress() public returns (address) {\n return other.getAddress();\n }\n}\n// ----\n// constructor(), 2000 wei ->\n// gas irOptimized: 114353\n// gas irOptimized code: 58800\n// gas legacy: 118617\n// gas legacy code: 111400\n// gas legacyOptimized: 114067\n// gas legacyOptimized code: 59800\n// balance -> 1500\n// gas irOptimized: 191881\n// gas legacy: 235167\n// gas legacyOptimized: 180756\n// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500\n" + }, + "format_raw_string_with_control_chars.sol": { + "content": "contract C {\n function f(string memory s) external pure returns (string memory) {\n return s;\n }\n}\n// NOTE: The test is here to illustrate the problem with formatting control chars in strings in\n// test expectations but unfortunately it can only be triggered manually. It does not test anything\n// unless you introduce a difference in expectations to force isoltest to reformat them.\n// ----\n// f(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" # Input/Output: \"\ud83d\ude03\ud83d\ude03\ud83d\ude03\ud83d\ude03\" #\n" + }, + "balance_with_balance2.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1 ether ->\n// balance -> 1000000000000000000\n" + }, + "builtins.sol": { + "content": "contract SmokeTest {\n}\n// ----\n// isoltest_builtin_test -> 0x1234\n" + }, + "effects.sol": { + "content": "contract SmokeTest {\n}\n// ----\n// isoltest_side_effects_test -> 0\n// isoltest_side_effects_test: 0x1234 -> 0x1234\n// ~ 0000000000000000000000000000000000000000000000000000000000001234\n// isoltest_side_effects_test: 0x1234, 0x2345 # comment # -> 0x1234, 0x2345\n// ~ 0000000000000000000000000000000000000000000000000000000000001234\n// ~ 0000000000000000000000000000000000000000000000000000000000002345\n// isoltest_side_effects_test: 0x1234, 0x2345, 0x3456 -> 0x1234, 0x2345, 0x3456 # comment #\n// ~ 0000000000000000000000000000000000000000000000000000000000001234\n// ~ 0000000000000000000000000000000000000000000000000000000000002345\n// ~ 0000000000000000000000000000000000000000000000000000000000003456\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars.sol b/examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars.sol new file mode 100644 index 00000000..a230cc9a --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars.sol @@ -0,0 +1,10 @@ +contract C { + function f(string memory s) external pure returns (string memory) { + return s; + } +} +// NOTE: The test is here to illustrate the problem with formatting control chars in strings in +// test expectations but unfortunately it can only be triggered manually. It does not test anything +// unless you introduce a difference in expectations to force isoltest to reformat them. +// ---- +// f(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" # Input/Output: "😃😃😃😃" # diff --git a/examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars_standard_input.json b/examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars_standard_input.json new file mode 100644 index 00000000..ba8166dd --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_format_raw_string_with_control_chars/format_raw_string_with_control_chars_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "balance_with_balance.sol": { + "content": "contract ClientReceipt {\n constructor() payable {}\n}\n// ----\n// constructor(), 1000 wei ->\n// balance -> 1000\n" + }, + "account.sol": { + "content": "contract AccountBuiltinTest {\n function who_am_i() public returns (address result) {\n result = msg.sender;\n }\n}\n// ----\n// constructor()\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// who_am_i() -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// account: 1 -> 0x1212121212121212121212121212120000001012\n// who_am_i() -> 0x1212121212121212121212121212120000001012\n// balance: 0x1212121212121212121212121212120000001012 -> 1267650600228229401496703205376\n// account: 2 -> 0x1212121212121212121212121212120000002012\n// who_am_i() -> 0x1212121212121212121212121212120000002012\n// balance: 0x1212121212121212121212121212120000002012 -> 1267650600228229401496703205376\n// account: 3 -> 0x1212121212121212121212121212120000003012\n// who_am_i() -> 0x1212121212121212121212121212120000003012\n// balance: 0x1212121212121212121212121212120000003012 -> 1267650600228229401496703205376\n// account: 4 -> 0x1212121212121212121212121212120000004012\n// who_am_i() -> 0x1212121212121212121212121212120000004012\n// balance: 0x1212121212121212121212121212120000004012 -> 1267650600228229401496703205376\n// account: 5 -> 0x1212121212121212121212121212120000005012\n// who_am_i() -> 0x1212121212121212121212121212120000005012\n// balance: 0x1212121212121212121212121212120000005012 -> 1267650600228229401496703205376\n// account: 6 -> 0x1212121212121212121212121212120000006012\n// who_am_i() -> 0x1212121212121212121212121212120000006012\n// balance: 0x1212121212121212121212121212120000006012 -> 1267650600228229401496703205376\n// account: 7 -> 0x1212121212121212121212121212120000007012\n// who_am_i() -> 0x1212121212121212121212121212120000007012\n// balance: 0x1212121212121212121212121212120000007012 -> 1267650600228229401496703205376\n// account: 8 -> 0x1212121212121212121212121212120000008012\n// who_am_i() -> 0x1212121212121212121212121212120000008012\n// balance: 0x1212121212121212121212121212120000008012 -> 1267650600228229401496703205376\n// account: 9 -> 0x1212121212121212121212121212120000009012\n// who_am_i() -> 0x1212121212121212121212121212120000009012\n// balance: 0x1212121212121212121212121212120000009012 -> 1267650600228229401496703205376\n// account: 10 -> 0x121212121212121212121212121212000000a012\n// who_am_i() -> 0x121212121212121212121212121212000000a012\n// balance: 0x121212121212121212121212121212000000a012 -> 0\n// account: 11 -> 0x121212121212121212121212121212000000b012\n// who_am_i() -> 0x121212121212121212121212121212000000b012\n// balance: 0x121212121212121212121212121212000000b012 -> 0\n// account: 12 -> 0x121212121212121212121212121212000000c012\n// who_am_i() -> 0x121212121212121212121212121212000000c012\n// balance: 0x121212121212121212121212121212000000c012 -> 0\n" + }, + "balance_without_balance.sol": { + "content": "contract ClientReceipt {\n}\n// ----\n// balance -> 0\n// balance: 0x0000000000000000000000000000000000000000 -> 0\n" + }, + "balance_other_contract.sol": { + "content": "contract Other {\n constructor() payable {\n }\n function getAddress() public returns (address) {\n return address(this);\n }\n}\ncontract ClientReceipt {\n Other other;\n constructor() payable {\n other = new Other{value:500}();\n }\n function getAddress() public returns (address) {\n return other.getAddress();\n }\n}\n// ----\n// constructor(), 2000 wei ->\n// gas irOptimized: 114353\n// gas irOptimized code: 58800\n// gas legacy: 118617\n// gas legacy code: 111400\n// gas legacyOptimized: 114067\n// gas legacyOptimized code: 59800\n// balance -> 1500\n// gas irOptimized: 191881\n// gas legacy: 235167\n// gas legacyOptimized: 180756\n// getAddress() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a\n// balance: 0x137aa4dfc0911524504fcd4d98501f179bc13b4a -> 500\n" + }, + "format_raw_string_with_control_chars.sol": { + "content": "contract C {\n function f(string memory s) external pure returns (string memory) {\n return s;\n }\n}\n// NOTE: The test is here to illustrate the problem with formatting control chars in strings in\n// test expectations but unfortunately it can only be triggered manually. It does not test anything\n// unless you introduce a difference in expectations to force isoltest to reformat them.\n// ----\n// f(string): 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" -> 0x20, 16, \"\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\\xf0\\x9f\\x98\\x83\" # Input/Output: \"\ud83d\ude03\ud83d\ude03\ud83d\ude03\ud83d\ude03\" #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty.sol b/examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty.sol new file mode 100644 index 00000000..11832a51 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty.sol @@ -0,0 +1,4 @@ +contract StorageEmpty { +} +// ---- +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty_standard_input.json b/examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty_standard_input.json new file mode 100644 index 00000000..27d5eb66 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_storage_storage_empty/storage_empty_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "storage_empty.sol": { + "content": "contract StorageEmpty {\n}\n// ----\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty.sol b/examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty.sol new file mode 100644 index 00000000..33b1a4d6 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty.sol @@ -0,0 +1,8 @@ +contract StorageNotEmpty { + uint256 x; + function set(uint256 _a) public { x = _a; } +} +// ---- +// storageEmpty -> 1 +// set(uint256): 1 -> +// storageEmpty -> 0 diff --git a/examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty_standard_input.json b/examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty_standard_input.json new file mode 100644 index 00000000..60d0c320 --- /dev/null +++ b/examples/test/semanticTests/isoltestTesting_storage_storage_nonempty/storage_nonempty_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "storage_empty.sol": { + "content": "contract StorageEmpty {\n}\n// ----\n// storageEmpty -> 1\n" + }, + "storage_nonempty.sol": { + "content": "contract StorageNotEmpty {\n uint256 x;\n function set(uint256 _a) public { x = _a; }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256): 1 ->\n// storageEmpty -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata.sol b/examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata.sol new file mode 100644 index 00000000..bc9e11de --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata.sol @@ -0,0 +1,17 @@ +library D { + function f(bytes calldata _x) internal pure returns (bytes1) { + return _x[0]; + } + function g(bytes memory _x) internal pure returns (bytes1) { + return _x[0]; + } +} + +contract C { + using D for bytes; + function f(bytes calldata _x) public pure returns (bytes1, bytes1) { + return (_x.f(), _x.g()); + } +} +// ---- +// f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata_standard_input.json b/examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata_standard_input.json new file mode 100644 index 00000000..3fb11466 --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_internal_library_function_accepting_calldata/attached_internal_library_function_accepting_calldata_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata.sol b/examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata.sol new file mode 100644 index 00000000..5c32d31e --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata.sol @@ -0,0 +1,17 @@ +library D { + function f(bytes calldata _x) internal pure returns (bytes calldata) { + return _x; + } + function g(bytes calldata _x) internal pure returns (bytes memory) { + return _x; + } +} + +contract C { + using D for bytes; + function f(bytes calldata _x) public pure returns (bytes1, bytes1) { + return (_x.f()[0], _x.g()[0]); + } +} +// ---- +// f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata_standard_input.json b/examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata_standard_input.json new file mode 100644 index 00000000..e395121e --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_internal_library_function_returning_calldata/attached_internal_library_function_returning_calldata_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata.sol.sol b/examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata.sol.sol new file mode 100644 index 00000000..1c1f0457 --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata.sol.sol @@ -0,0 +1,20 @@ +library D { + function f(bytes calldata _x) public pure returns (bytes1) { + return _x[0]; + } + function g(bytes memory _x) public pure returns (bytes1) { + return _x[0]; + } +} + +contract C { + using D for bytes; + function f(bytes calldata _x) public pure returns (bytes1, bytes1) { + return (_x.f(), _x.g()); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: D +// f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata_standard_input.json b/examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata_standard_input.json new file mode 100644 index 00000000..556e4f2b --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_public_library_function_accepting_calldata/attached_public_library_function_accepting_calldata_standard_input.json @@ -0,0 +1,211 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + }, + "internal_library_function_attached_to_literal.sol": { + "content": "library L {\n function double(uint a) internal pure returns (uint) {\n return a * 2;\n }\n\n function double(bytes memory a) internal pure returns (bytes memory) {\n return bytes.concat(a, a);\n }\n}\n\ncontract C {\n using L for *;\n\n function double42() public returns (uint) {\n return 42.double();\n }\n\n function doubleABC() public returns (bytes memory) {\n return \"abc\".double();\n }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n" + }, + "stub.sol": { + "content": "library L {\n function f(uint256 v) external returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// library: L\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "external_call_with_function_pointer_parameter.sol": { + "content": "library L {\n function run(\n function(uint256) external returns (uint256) _operation,\n uint256 _a\n )\n external\n returns (uint256)\n {\n return _operation(_a);\n }\n}\n\ncontract C {\n function double(uint256 _a) external returns (uint256) {\n return _a * _a;\n }\n\n function g(uint256 _value) external returns (uint256) {\n return L.run(this.double, _value);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "attached_public_library_function_accepting_calldata.sol.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) public pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata.sol b/examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata.sol new file mode 100644 index 00000000..c194af88 --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata.sol @@ -0,0 +1,20 @@ +library D { + function f(bytes calldata _x) public pure returns (bytes calldata) { + return _x; + } + function g(bytes calldata _x) public pure returns (bytes memory) { + return _x; + } +} + +contract C { + using D for bytes; + function f(bytes calldata _x) public pure returns (bytes1, bytes1) { + return (_x.f()[0], _x.g()[0]); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: D +// f(bytes): 0x20, 4, "abcd" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata_standard_input.json b/examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata_standard_input.json new file mode 100644 index 00000000..9ef6c4ae --- /dev/null +++ b/examples/test/semanticTests/libraries_attached_public_library_function_returning_calldata/attached_public_library_function_returning_calldata_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter.sol b/examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter.sol new file mode 100644 index 00000000..1808d613 --- /dev/null +++ b/examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter.sol @@ -0,0 +1,24 @@ +library L { + function run( + function(uint256) external returns (uint256) _operation, + uint256 _a + ) + external + returns (uint256) + { + return _operation(_a); + } +} + +contract C { + function double(uint256 _a) external returns (uint256) { + return _a * _a; + } + + function g(uint256 _value) external returns (uint256) { + return L.run(this.double, _value); + } +} +// ---- +// library: L +// g(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter_standard_input.json b/examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter_standard_input.json new file mode 100644 index 00000000..e005d34d --- /dev/null +++ b/examples/test/semanticTests/libraries_external_call_with_function_pointer_parameter/external_call_with_function_pointer_parameter_standard_input.json @@ -0,0 +1,208 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + }, + "internal_library_function_attached_to_literal.sol": { + "content": "library L {\n function double(uint a) internal pure returns (uint) {\n return a * 2;\n }\n\n function double(bytes memory a) internal pure returns (bytes memory) {\n return bytes.concat(a, a);\n }\n}\n\ncontract C {\n using L for *;\n\n function double42() public returns (uint) {\n return 42.double();\n }\n\n function doubleABC() public returns (bytes memory) {\n return \"abc\".double();\n }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n" + }, + "stub.sol": { + "content": "library L {\n function f(uint256 v) external returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// library: L\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "external_call_with_function_pointer_parameter.sol": { + "content": "library L {\n function run(\n function(uint256) external returns (uint256) _operation,\n uint256 _a\n )\n external\n returns (uint256)\n {\n return _operation(_a);\n }\n}\n\ncontract C {\n function double(uint256 _a) external returns (uint256) {\n return _a * _a;\n }\n\n function g(uint256 _value) external returns (uint256) {\n return L.run(this.double, _value);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter.sol b/examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter.sol new file mode 100644 index 00000000..e842feca --- /dev/null +++ b/examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter.sol @@ -0,0 +1,17 @@ +library L { + function f(uint256[2] storage _a) external returns (uint256) { + return _a[0] * _a[1]; + } +} + +contract C { + uint256[2] x; + + function g(uint256 _value) external returns (uint256) { + x[0] = x[1] = _value; + return L.f(x); + } +} +// ---- +// library: L +// g(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter_standard_input.json b/examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter_standard_input.json new file mode 100644 index 00000000..2b84af36 --- /dev/null +++ b/examples/test/semanticTests/libraries_external_call_with_storage_array_parameter/external_call_with_storage_array_parameter_standard_input.json @@ -0,0 +1,190 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter.sol b/examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter.sol new file mode 100644 index 00000000..d009bed5 --- /dev/null +++ b/examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter.sol @@ -0,0 +1,17 @@ +library L { + function f(mapping(uint256 => uint256) storage _a) external returns (uint256) { + return _a[0] * _a[1]; + } +} + +contract C { + mapping(uint256 => uint256) x; + + function g(uint256 _value) external returns (uint256) { + x[0] = x[1] = _value; + return L.f(x); + } +} +// ---- +// library: L +// g(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter_standard_input.json b/examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter_standard_input.json new file mode 100644 index 00000000..253118d2 --- /dev/null +++ b/examples/test/semanticTests/libraries_external_call_with_storage_mapping_parameter/external_call_with_storage_mapping_parameter_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses.sol b/examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses.sol new file mode 100644 index 00000000..1fa930ac --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses.sol @@ -0,0 +1,24 @@ +library L { + struct S { + uint256[] data; + } + + function f(S memory _s) internal { + _s.data[3] += 2; + } +} + + +contract C { + using L for L.S; + + function f() public returns (uint256) { + L.S memory x; + x.data = new uint256[](7); + x.data[3] = 8; + (x.f)(); + return x.data[3]; + } +} +// ---- +// f() -> 0x0a diff --git a/examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses_standard_input.json b/examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses_standard_input.json new file mode 100644 index 00000000..4846a5bd --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_call_attached_with_parentheses/internal_call_attached_with_parentheses_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses.sol b/examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses.sol new file mode 100644 index 00000000..5a76dabd --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses.sol @@ -0,0 +1,13 @@ +library L { + function f() internal returns (uint) { + return 3; + } +} + +contract C { + function foo() public returns (uint) { + return (L.f)(); + } +} +// ---- +// foo() -> 3 diff --git a/examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses_standard_input.json b/examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses_standard_input.json new file mode 100644 index 00000000..94ef5d59 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_call_unattached_with_parentheses/internal_call_unattached_with_parentheses_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function/internal_library_function.sol b/examples/test/semanticTests/libraries_internal_library_function/internal_library_function.sol new file mode 100644 index 00000000..24299b6d --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function/internal_library_function.sol @@ -0,0 +1,20 @@ +// tests that internal library functions can be called from outside +// and retain the same memory context (i.e. are pulled into the caller's code) +// This has to work without linking, because everything will be inlined. +library L { + function f(uint256[] memory _data) internal { + _data[3] = 2; + } +} + + +contract C { + function f() public returns (uint256) { + uint256[] memory x = new uint256[](7); + x[3] = 8; + L.f(x); + return x[3]; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/libraries_internal_library_function/internal_library_function_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function/internal_library_function_standard_input.json new file mode 100644 index 00000000..b1af4755 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function/internal_library_function_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address.sol new file mode 100644 index 00000000..c5581b79 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address.sol @@ -0,0 +1,16 @@ +library L { + function equals(address a, address b) internal pure returns (bool) { + return a == b; + } +} + +contract C { + using L for address; + + function foo(address a, address b) public returns (bool) { + return a.equals(b); + } +} +// ---- +// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true +// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address_standard_input.json new file mode 100644 index 00000000..09888a1f --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address/internal_library_function_attached_to_address_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer.sol new file mode 100644 index 00000000..a4facc02 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer.sol @@ -0,0 +1,19 @@ +library L { + function transfer(address a) internal {} + function send(address a) internal {} +} + +contract C { + using L for address; + + function useTransfer(address a) public { + a.transfer(); + } + + function useSend(address a) public { + a.send(); + } +} +// ---- +// useTransfer(address): 0x111122223333444455556666777788889999aAaa -> +// useSend(address): 0x111122223333444455556666777788889999aAaa -> diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer_standard_input.json new file mode 100644 index 00000000..ad68c3cd --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_address_named_send_transfer/internal_library_function_attached_to_address_named_send_transfer_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push.sol new file mode 100644 index 00000000..80e0153b --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push.sol @@ -0,0 +1,17 @@ +library L { + function pop(uint[2] memory a) internal {} + function push(uint[2] memory a) internal {} +} + +contract C { + using L for uint[2]; + + function test() public { + uint[2] memory input; + + input.push(); + input.pop(); + } +} +// ---- +// test() -> diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push_standard_input.json new file mode 100644 index 00000000..4632c6e0 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_array_named_pop_push/internal_library_function_attached_to_array_named_pop_push_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool.sol new file mode 100644 index 00000000..bf49f4e7 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool.sol @@ -0,0 +1,18 @@ +library L { + function xor(bool a, bool b) internal pure returns (bool) { + return a != b; + } +} + +contract C { + using L for bool; + + function foo(bool a, bool b) public returns (bool) { + return a.xor(b); + } +} +// ---- +// foo(bool,bool): true, true -> false +// foo(bool,bool): true, false -> true +// foo(bool,bool): false, true -> true +// foo(bool,bool): false, false -> false diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool_standard_input.json new file mode 100644 index 00000000..7362f207 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_bool/internal_library_function_attached_to_bool_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract.sol new file mode 100644 index 00000000..a4a25f51 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract.sol @@ -0,0 +1,18 @@ +contract E {} + +library L { + function foo(E e) internal pure returns (uint) { + return 42; + } +} + +contract C { + using L for E; + + function test() public returns (uint) { + E e = new E(); + return e.foo(); + } +} +// ---- +// test() -> 42 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract_standard_input.json new file mode 100644 index 00000000..6e18a511 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_contract/internal_library_function_attached_to_contract_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array.sol new file mode 100644 index 00000000..f759ea78 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array.sol @@ -0,0 +1,19 @@ +library L { + function at(uint[] memory a, uint i) internal pure returns (uint) { + return a[i]; + } +} + +contract C { + using L for uint[]; + + function secondItem() public returns (uint) { + uint[] memory input = new uint[](2); + input[0] = 0x11; + input[1] = 0x22; + + return input.at(1); + } +} +// ---- +// secondItem() -> 0x22 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array_standard_input.json new file mode 100644 index 00000000..3826e1c9 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_dynamic_array/internal_library_function_attached_to_dynamic_array_standard_input.json @@ -0,0 +1,199 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum.sol new file mode 100644 index 00000000..4dd3bad4 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum.sol @@ -0,0 +1,19 @@ +library L { + enum E { A, B } + + function equals(E a, E b) internal pure returns (bool) { + return a == b; + } +} + +contract C { + using L for L.E; + + function equalsA(uint choice) public returns (bool) { + L.E x = L.E.A; + return x.equals(L.E(choice)); + } +} +// ---- +// equalsA(uint256): 0 -> true +// equalsA(uint256): 1 -> false diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum_standard_input.json new file mode 100644 index 00000000..1541beff --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_enum/internal_library_function_attached_to_enum_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type.sol new file mode 100644 index 00000000..a2473e7e --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type.sol @@ -0,0 +1,20 @@ +library L { + // NOTE: External function takes up two stack slots + function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) { + return f(x) * 2; + } +} + +contract C { + using L for function(uint) external pure returns (uint); + + function identity(uint x) external pure returns (uint) { + return x; + } + + function test(uint value) public returns (uint) { + return this.identity.double(value); + } +} +// ---- +// test(uint256): 5 -> 10 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type_standard_input.json new file mode 100644 index 00000000..fb4d0c9f --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_external_function_type/internal_library_function_attached_to_external_function_type_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array.sol new file mode 100644 index 00000000..28f621d5 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array.sol @@ -0,0 +1,19 @@ +library L { + function at(uint[2] memory a, uint i) internal pure returns (uint) { + return a[i]; + } +} + +contract C { + using L for uint[2]; + + function secondItem() public returns (uint) { + uint[2] memory input; + input[0] = 0x11; + input[1] = 0x22; + + return input.at(1); + } +} +// ---- +// secondItem() -> 0x22 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array_standard_input.json new file mode 100644 index 00000000..87bf2dd6 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_array/internal_library_function_attached_to_fixed_array_standard_input.json @@ -0,0 +1,217 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + }, + "internal_library_function_attached_to_literal.sol": { + "content": "library L {\n function double(uint a) internal pure returns (uint) {\n return a * 2;\n }\n\n function double(bytes memory a) internal pure returns (bytes memory) {\n return bytes.concat(a, a);\n }\n}\n\ncontract C {\n using L for *;\n\n function double42() public returns (uint) {\n return 42.double();\n }\n\n function doubleABC() public returns (bytes memory) {\n return \"abc\".double();\n }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n" + }, + "stub.sol": { + "content": "library L {\n function f(uint256 v) external returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// library: L\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "external_call_with_function_pointer_parameter.sol": { + "content": "library L {\n function run(\n function(uint256) external returns (uint256) _operation,\n uint256 _a\n )\n external\n returns (uint256)\n {\n return _operation(_a);\n }\n}\n\ncontract C {\n function double(uint256 _a) external returns (uint256) {\n return _a * _a;\n }\n\n function g(uint256 _value) external returns (uint256) {\n return L.run(this.double, _value);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "attached_public_library_function_accepting_calldata.sol.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) public pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_returns_in_library_named.sol": { + "content": "library Lib {\n function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r)\n {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 21;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.f(a, b)[2] = 84;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function g() public returns (uint, uint, uint, uint, uint, uint)\n {\n mapping(uint => uint) storage m = Lib.f(a, b);\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 0, 0x2a, 0, 0, 0x15, 0x54\n// g() -> 0, 0x2a, 0, 0, 0x15, 0x11\n" + }, + "internal_library_function_attached_to_fixed_array.sol": { + "content": "library L {\n function at(uint[2] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[2];\n\n function secondItem() public returns (uint) {\n uint[2] memory input;\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes.sol new file mode 100644 index 00000000..bf7d0ede --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes.sol @@ -0,0 +1,15 @@ +library L { + function add(bytes2 a, bytes2 b) internal pure returns (bytes2) { + return bytes2(uint16(a) + uint16(b)); + } +} + +contract C { + using L for bytes2; + + function sum(bytes2 a, bytes2 b) public returns (bytes2) { + return a.add(b); + } +} +// ---- +// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122) diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes_standard_input.json new file mode 100644 index 00000000..66e6f020 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_fixed_bytes/internal_library_function_attached_to_fixed_bytes_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer.sol new file mode 100644 index 00000000..5234fb5e --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer.sol @@ -0,0 +1,15 @@ +library L { + function add(uint256 a, uint256 b) internal pure returns (uint256) { + return a + b; + } +} + +contract C { + using L for uint256; + + function foo(uint256 a, uint256 b) public returns (uint256) { + return a.add(b); + } +} +// ---- +// foo(uint256,uint256): 8, 42 -> 50 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer_standard_input.json new file mode 100644 index 00000000..6b8a7426 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_integer/internal_library_function_attached_to_integer_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface.sol new file mode 100644 index 00000000..13228115 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface.sol @@ -0,0 +1,19 @@ +interface I {} +contract E is I {} + +library L { + function foo(I i) internal pure returns (uint) { + return 42; + } +} + +contract C { + using L for I; + + function test() public returns (uint) { + E e = new E(); + return I(e).foo(); + } +} +// ---- +// test() -> 42 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface_standard_input.json new file mode 100644 index 00000000..941d3acb --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_interface/internal_library_function_attached_to_interface_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type.sol new file mode 100644 index 00000000..4397711c --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type.sol @@ -0,0 +1,19 @@ +library L { + function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) { + return f(x) * 2; + } +} + +contract C { + using L for function(uint) internal pure returns (uint); + + function identity(uint x) internal pure returns (uint) { + return x; + } + + function test(uint value) public returns (uint) { + return identity.double(value); + } +} +// ---- +// test(uint256): 5 -> 10 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type_standard_input.json new file mode 100644 index 00000000..a3e5a41a --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type/internal_library_function_attached_to_internal_function_type_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector.sol new file mode 100644 index 00000000..4305b6d4 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector.sol @@ -0,0 +1,19 @@ +library L { + function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) { + return f(x) * 2; + } +} + +contract C { + using L for function(uint) internal pure returns (uint); + + function identity(uint x) internal pure returns (uint) { + return x; + } + + function test(uint value) public returns (uint) { + return identity.selector(value); + } +} +// ---- +// test(uint256): 5 -> 10 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector_standard_input.json new file mode 100644 index 00000000..2ab67830 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_internal_function_type_named_selector/internal_library_function_attached_to_internal_function_type_named_selector_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal.sol new file mode 100644 index 00000000..da7ee6cc --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal.sol @@ -0,0 +1,24 @@ +library L { + function double(uint a) internal pure returns (uint) { + return a * 2; + } + + function double(bytes memory a) internal pure returns (bytes memory) { + return bytes.concat(a, a); + } +} + +contract C { + using L for *; + + function double42() public returns (uint) { + return 42.double(); + } + + function doubleABC() public returns (bytes memory) { + return "abc".double(); + } +} +// ---- +// double42() -> 84 +// doubleABC() -> 0x20, 6, "abcabc" diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal_standard_input.json new file mode 100644 index 00000000..08759f13 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_literal/internal_library_function_attached_to_literal_standard_input.json @@ -0,0 +1,202 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + }, + "internal_library_function_attached_to_literal.sol": { + "content": "library L {\n function double(uint a) internal pure returns (uint) {\n return a * 2;\n }\n\n function double(bytes memory a) internal pure returns (bytes memory) {\n return bytes.concat(a, a);\n }\n}\n\ncontract C {\n using L for *;\n\n function double42() public returns (uint) {\n return 42.double();\n }\n\n function doubleABC() public returns (bytes memory) {\n return \"abc\".double();\n }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping.sol new file mode 100644 index 00000000..d4cee5c9 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping.sol @@ -0,0 +1,20 @@ +library L { + function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) { + return a[i]; + } +} + +contract C { + using L for mapping(uint => uint); + + mapping(uint => uint) map; + + function mapValue(uint a) public returns (uint) { + map[42] = 0x24; + map[66] = 0x66; + + return map.at(a); + } +} +// ---- +// mapValue(uint256): 42 -> 0x24 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping_standard_input.json new file mode 100644 index 00000000..0d9bbaa0 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_mapping/internal_library_function_attached_to_mapping_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory.sol new file mode 100644 index 00000000..3ed398f9 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory.sol @@ -0,0 +1,16 @@ +library L { + function at(string memory a, uint i) internal pure returns (uint8) { + return uint8(bytes(a)[i]); + } +} + +contract C { + using L for string; + + function secondChar() public returns (uint8) { + string memory input = "abc"; + return input.at(1); + } +} +// ---- +// secondChar() -> 98 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory_standard_input.json new file mode 100644 index 00000000..76ffb38b --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_memory/internal_library_function_attached_to_string_accepting_memory_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage.sol new file mode 100644 index 00000000..b7bc103f --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage.sol @@ -0,0 +1,20 @@ +library L { + function f(string memory a) internal pure returns (string memory) { + return a; + } + function g(string storage a) internal pure returns (string memory) { + return a; + } +} + +contract C { + using L for string; + string s; + + function test(string calldata x) public returns (string memory, string memory) { + s = x; + return (s.f(), s.g()); + } +} +// ---- +// test(string): 0x20, 3, "def" -> 0x40, 0x80, 3, "def", 3, "def" diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage_standard_input.json new file mode 100644 index 00000000..61e66dc7 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_string_accepting_storage/internal_library_function_attached_to_string_accepting_storage_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct.sol b/examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct.sol new file mode 100644 index 00000000..e9f95c0a --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct.sol @@ -0,0 +1,25 @@ +// This has to work without linking, because everything will be inlined. +library L { + struct S { + uint256[] data; + } + + function f(S memory _s) internal { + _s.data[3] = 2; + } +} + + +contract C { + using L for L.S; + + function f() public returns (uint256) { + L.S memory x; + x.data = new uint256[](7); + x.data[3] = 8; + x.f(); + return x.data[3]; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct_standard_input.json new file mode 100644 index 00000000..817f7507 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_attached_to_struct/internal_library_function_attached_to_struct_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private.sol b/examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private.sol new file mode 100644 index 00000000..5ef12f69 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private.sol @@ -0,0 +1,25 @@ +// tests that internal library functions that are called from outside and that +// themselves call private functions are still able to (i.e. the private function +// also has to be pulled into the caller's code) +// This has to work without linking, because everything will be inlined. +library L { + function g(uint256[] memory _data) private { + _data[3] = 2; + } + + function f(uint256[] memory _data) internal { + g(_data); + } +} + + +contract C { + function f() public returns (uint256) { + uint256[] memory x = new uint256[](7); + x[3] = 8; + L.f(x); + return x[3]; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private_standard_input.json new file mode 100644 index 00000000..0f809fca --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_calling_private/internal_library_function_calling_private_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer.sol b/examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer.sol new file mode 100644 index 00000000..0681fd0d --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer.sol @@ -0,0 +1,15 @@ +library L { + function f() internal returns (uint) { + return 66; + } +} + +contract C { + function g() public returns (uint) { + function() internal returns(uint) ptr; + ptr = L.f; + return ptr(); + } +} +// ---- +// g() -> 66 diff --git a/examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer_standard_input.json new file mode 100644 index 00000000..e47fb143 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_pointer/internal_library_function_pointer_standard_input.json @@ -0,0 +1,193 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size.sol b/examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size.sol new file mode 100644 index 00000000..d6e0e926 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size.sol @@ -0,0 +1,25 @@ +// This has to work without linking, because everything will be inlined. +library L { + struct S { + uint256[] data; + } + + function f(S memory _s) internal returns (uint256[] memory) { + _s.data[3] = 2; + return _s.data; + } +} + + +contract C { + using L for L.S; + + function f() public returns (uint256) { + L.S memory x; + x.data = new uint256[](7); + x.data[3] = 8; + return x.f()[3]; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size_standard_input.json b/examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size_standard_input.json new file mode 100644 index 00000000..7df9d2f6 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_library_function_return_var_size/internal_library_function_return_var_size_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library.sol b/examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library.sol new file mode 100644 index 00000000..d59cedfd --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library.sol @@ -0,0 +1,27 @@ +library Lib { + function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint) + { + for (uint i = 0; i < _haystack.length; ++i) + if (_haystack[i] == _needle) + return i; + return type(uint).max; + } +} +contract Test { + mapping(string => uint16[]) data; + function f() public returns (uint a, uint b) + { + while (data["abc"].length < 20) + data["abc"].push(); + data["abc"][4] = 9; + data["abc"][17] = 3; + a = Lib.find(data["abc"], 9); + b = Lib.find(data["abc"], 3); + } +} +// ---- +// library: Lib +// f() -> 4, 0x11 +// gas irOptimized: 111419 +// gas legacy: 132930 +// gas legacyOptimized: 118020 diff --git a/examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library_standard_input.json b/examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library_standard_input.json new file mode 100644 index 00000000..ee56b785 --- /dev/null +++ b/examples/test/semanticTests/libraries_internal_types_in_library/internal_types_in_library_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_address/library_address.sol b/examples/test/semanticTests/libraries_library_address/library_address.sol new file mode 100644 index 00000000..6ca06444 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_address/library_address.sol @@ -0,0 +1,56 @@ +library L { + function f(uint256 v) external pure returns (uint) { + return v * v; + } + function g(uint256 v) external returns (uint) { + return v * v; + } +} +contract C { + function addr() public view returns (bool) { + return address(L) == address(0); + } + function g(uint256 v) public view returns (uint256) { + return L.f(v); + } + function h(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature("f(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } + function i(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature("f(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } + function j(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature("g(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } + function k(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature("g(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// library: L +// addr() -> false +// g(uint256): 1 -> 1 +// g(uint256): 2 -> 4 +// g(uint256): 4 -> 16 +// h(uint256): 1 -> 1 +// h(uint256): 2 -> 4 +// h(uint256): 4 -> 16 +// i(uint256): 1 -> 1 +// i(uint256): 2 -> 4 +// i(uint256): 4 -> 16 +// j(uint256): 1 -> 1 +// j(uint256): 2 -> 4 +// j(uint256): 4 -> 16 +// k(uint256): 1 -> FAILURE, hex"4e487b71", 0x01 +// k(uint256): 2 -> FAILURE, hex"4e487b71", 0x01 +// k(uint256): 4 -> FAILURE, hex"4e487b71", 0x01 diff --git a/examples/test/semanticTests/libraries_library_address/library_address_standard_input.json b/examples/test/semanticTests/libraries_library_address/library_address_standard_input.json new file mode 100644 index 00000000..e2c9e061 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_address/library_address_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead.sol b/examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead.sol new file mode 100644 index 00000000..ce7344f4 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead.sol @@ -0,0 +1,24 @@ +library L { + function f(uint256 a, uint256 b) external { + assert(a * a == b); + } +} +contract C { + function addr() public view returns (bool) { + return address(L) == address(0); + } + function g(uint256 a, uint256 b) public returns (bool) { + (bool success,) = address(L).delegatecall(abi.encodeWithSignature("f(uint256,uint256)", a, b)); + return success; + } +} +// ---- +// library: L +// g(uint256,uint256): 1, 1 -> true +// g(uint256,uint256): 1, 2 -> false +// g(uint256,uint256): 2, 3 -> false +// g(uint256,uint256): 2, 4 -> true +// g(uint256,uint256): 2, 5 -> false +// g(uint256,uint256): 4, 15 -> false +// g(uint256,uint256): 4, 16 -> true +// g(uint256,uint256): 4, 17 -> false diff --git a/examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead_standard_input.json b/examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead_standard_input.json new file mode 100644 index 00000000..b749f598 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_address_homestead/library_address_homestead_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module.sol b/examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module.sol new file mode 100644 index 00000000..4c964690 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module.sol @@ -0,0 +1,60 @@ +==== Source: a.sol ==== + +import "a.sol" as M; + +library L { + function f(uint256 v) external pure returns (uint) { + return v * v; + } + function g(uint256 v) external returns (uint) { + return v * v; + } +} +contract C { + function addr() public view returns (bool) { + return address(M.L) == address(0); + } + function g(uint256 v) public view returns (uint256) { + return M.L.f(v); + } + function h(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature("f(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } + function i(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature("f(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } + function j(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature("g(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } + function k(uint256 v) public returns (uint256) { + (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature("g(uint256)", v)); + assert(success); + return abi.decode(result, (uint256)); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// library: "a.sol":L +// addr() -> false +// g(uint256): 1 -> 1 +// g(uint256): 2 -> 4 +// g(uint256): 4 -> 16 +// h(uint256): 1 -> 1 +// h(uint256): 2 -> 4 +// h(uint256): 4 -> 16 +// i(uint256): 1 -> 1 +// i(uint256): 2 -> 4 +// i(uint256): 4 -> 16 +// j(uint256): 1 -> 1 +// j(uint256): 2 -> 4 +// j(uint256): 4 -> 16 +// k(uint256): 1 -> FAILURE, hex"4e487b71", 0x01 +// k(uint256): 2 -> FAILURE, hex"4e487b71", 0x01 +// k(uint256): 4 -> FAILURE, hex"4e487b71", 0x01 diff --git a/examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module_standard_input.json b/examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module_standard_input.json new file mode 100644 index 00000000..4544ca2d --- /dev/null +++ b/examples/test/semanticTests/libraries_library_address_via_module/library_address_via_module_standard_input.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead.sol b/examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead.sol new file mode 100644 index 00000000..44526da6 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead.sol @@ -0,0 +1,13 @@ +library Lib { function m() public returns (address) { return msg.sender; } } +contract Test { + address public sender; + function f() public { + sender = Lib.m(); + } +} +// ==== +// EVMVersion: >=homestead +// ---- +// library: Lib +// f() -> +// sender() -> 0x1212121212121212121212121212120000000012 diff --git a/examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead_standard_input.json b/examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead_standard_input.json new file mode 100644 index 00000000..96c12f59 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_call_in_homestead/library_call_in_homestead_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure.sol b/examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure.sol new file mode 100644 index 00000000..b540e9a6 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure.sol @@ -0,0 +1,32 @@ +library L { + function f(uint256[] storage x) public pure returns (uint256) { + return 23; + } +} +contract C { + uint256[] y; + string x; + constructor() { y.push(42); } + function f() public view returns (uint256) { + return L.f(y); + } + function g() public returns (bool, uint256) { + uint256 ys; + assembly { ys := y.slot } + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } + function h() public returns (bool, uint256) { + uint256 ys; + assembly { ys := y.slot } + (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f() -> 23 +// g() -> true, 23 +// h() -> true, 23 diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure_standard_input.json b/examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure_standard_input.json new file mode 100644 index 00000000..69c3ea30 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_pure/library_delegatecall_guard_pure_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed.sol b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed.sol new file mode 100644 index 00000000..3c527499 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed.sol @@ -0,0 +1,32 @@ +library L { + function f(uint256[] storage x) public view returns (uint256) { + return x.length; + } +} +contract C { + uint256[] y; + string x; + constructor() { y.push(42); } + function f() public view returns (uint256) { + return L.f(y); + } + function g() public returns (bool, uint256) { + uint256 ys; + assembly { ys := y.slot } + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } + function h() public returns (bool, uint256) { + uint256 ys; + assembly { ys := y.slot } + (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f() -> 1 +// g() -> true, 1 +// h() -> true, 0 # this is bad - this should fail! # diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed_standard_input.json b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed_standard_input.json new file mode 100644 index 00000000..8bfcdc50 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_needed/library_delegatecall_guard_view_needed_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed.sol b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed.sol new file mode 100644 index 00000000..2d4e6468 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed.sol @@ -0,0 +1,31 @@ +library L { + function f(uint256[] storage x) public view returns (uint256) { + return 84; + } +} +contract C { + uint256[] y; + constructor() { y.push(42); } + function f() public view returns (uint256) { + return L.f(y); + } + function g() public returns (bool, uint256) { + uint256 ys; + assembly { ys := y.slot } + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } + function h() public returns (bool, uint256) { + uint256 ys; + assembly { ys := y.slot } + (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f() -> 84 +// g() -> true, 84 +// h() -> true, 84 diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed_standard_input.json b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed_standard_input.json new file mode 100644 index 00000000..e0a6809f --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_not_needed/library_delegatecall_guard_view_not_needed_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall.sol b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall.sol new file mode 100644 index 00000000..d8cdb9a4 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall.sol @@ -0,0 +1,31 @@ +contract D { + uint public x; + constructor() { x = 42; } +} +library L { + function f(D d) public view returns (uint256) { + return d.x(); + } +} +contract C { + D d; + constructor() { d = new D(); } + function f() public view returns (uint256) { + return L.f(d); + } + function g() public returns (bool, uint256) { + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } + function h() public returns (bool, uint256) { + (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d)); + return (success, success ? abi.decode(data,(uint256)) : 0); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f() -> 42 +// g() -> true, 42 +// h() -> true, 42 diff --git a/examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall_standard_input.json b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall_standard_input.json new file mode 100644 index 00000000..9ad54bc6 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_delegatecall_guard_view_staticcall/library_delegatecall_guard_view_staticcall_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression.sol b/examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression.sol new file mode 100644 index 00000000..a385fb29 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression.sol @@ -0,0 +1,13 @@ +library Arst { + enum Foo {Things, Stuff} +} + + +contract Tsra { + function f() public returns (uint256) { + Arst.Foo; + return 1; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression_standard_input.json b/examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression_standard_input.json new file mode 100644 index 00000000..a51357ab --- /dev/null +++ b/examples/test/semanticTests/libraries_library_enum_as_an_expression/library_enum_as_an_expression_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors.sol b/examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors.sol new file mode 100644 index 00000000..baeb5ced --- /dev/null +++ b/examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors.sol @@ -0,0 +1,30 @@ +library L { + function f(uint256 x) external returns (uint) { return x; } + function g(uint256[] storage s) external returns (uint) { return s.length; } + function h(uint256[] memory m) public returns (uint) { return m.length; } +} +contract C { + uint256[] s; + constructor() { while (s.length < 42) s.push(0); } + function f() public returns (bool, bool, uint256) { + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7)); + return (L.f.selector == bytes4(keccak256("f(uint256)")), success, abi.decode(data, (uint256))); + } + function g() public returns (bool, bool, uint256) { + uint256 s_ptr; + assembly { s_ptr := s.slot } + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr)); + return (L.g.selector == bytes4(keccak256("g(uint256[] storage)")), success, abi.decode(data, (uint256))); + } + function h() public returns (bool, bool, uint256) { + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23))); + return (L.h.selector == bytes4(keccak256("h(uint256[])")), success, abi.decode(data, (uint256))); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f() -> true, true, 7 +// g() -> true, true, 42 +// h() -> true, true, 23 diff --git a/examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors_standard_input.json b/examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors_standard_input.json new file mode 100644 index 00000000..04d5eb32 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_function_selectors/library_function_selectors_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct.sol b/examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct.sol new file mode 100644 index 00000000..186fad7d --- /dev/null +++ b/examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct.sol @@ -0,0 +1,27 @@ +pragma abicoder v2; +library L { + struct S { uint256 a; } + function f(S storage s) external returns (uint) { return s.a; } + function g(S memory m) public returns (uint) { return m.a; } +} +contract C { + L.S s; + constructor() { s.a = 42; } + + function f() public returns (bool, bool, uint256) { + uint256 s_ptr; + assembly { s_ptr := s.slot } + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr)); + return (L.f.selector == bytes4(keccak256("f(L.S storage)")), success, abi.decode(data, (uint256))); + } + function g() public returns (bool, bool, uint256) { + (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23))); + return (L.g.selector == bytes4(keccak256("g(L.S)")), success, abi.decode(data, (uint256))); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// library: L +// f() -> true, true, 42 +// g() -> true, true, 23 diff --git a/examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct_standard_input.json b/examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct_standard_input.json new file mode 100644 index 00000000..35ede327 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_function_selectors_struct/library_function_selectors_struct_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve.sol b/examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve.sol new file mode 100644 index 00000000..41c16d2f --- /dev/null +++ b/examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve.sol @@ -0,0 +1,47 @@ +library L1 { + function add(uint256 a, uint256 b) external pure returns (uint256) { + return a + b + 1; + } +} + +library L2 { + function add(uint256 a, uint256 b) external pure returns (uint256) { + return a + b + 2; + } +} + +contract A { + uint256 sum; + constructor() { + sum = L1.add(1, 2); + } + function getSum() external view returns(uint256) { + return sum; + } +} + +contract B { + uint256 sum; + constructor() { + sum = L2.add(1, 2); + } + function getSum() external view returns(uint256) { + return sum; + } +} + +contract C { + A a = new A(); + B b = new B(); + function aSum() external view returns(uint256) { + return a.getSum(); + } + function bSum() external view returns(uint256) { + return b.getSum(); + } +} +// ---- +// library: L1 +// library: L2 +// aSum() -> 4 +// bSum() -> 5 diff --git a/examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve_standard_input.json b/examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve_standard_input.json new file mode 100644 index 00000000..4d1cfcad --- /dev/null +++ b/examples/test/semanticTests/libraries_library_references_preserve/library_references_preserve_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping.sol b/examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping.sol new file mode 100644 index 00000000..00001a2f --- /dev/null +++ b/examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +library Lib { + struct Items { + mapping (uint => uint) a; + } + + function get() public returns (Items storage x) { + assembly { x.slot := 123 } + } +} + +contract C { + function f() public returns(uint256 slot) { + Lib.Items storage ptr = Lib.get(); + assembly { slot := ptr.slot } + } +} +// ---- +// library: Lib +// f() -> 123 diff --git a/examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping_standard_input.json b/examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping_standard_input.json new file mode 100644 index 00000000..fad5acb6 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_return_struct_with_mapping/library_return_struct_with_mapping_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall.sol b/examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall.sol new file mode 100644 index 00000000..e7692ed8 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall.sol @@ -0,0 +1,18 @@ +library Lib { + function x() public view returns (uint) { + return 1; + } +} +contract Test { + uint t; + function f() public returns (uint) { + t = 2; + return this.g(); + } + function g() public view returns (uint) { + return Lib.x(); + } +} +// ---- +// library: Lib +// f() -> 1 diff --git a/examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall_standard_input.json b/examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall_standard_input.json new file mode 100644 index 00000000..db421d68 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_staticcall_delegatecall/library_staticcall_delegatecall_standard_input.json @@ -0,0 +1,196 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_stray_values/library_stray_values.sol b/examples/test/semanticTests/libraries_library_stray_values/library_stray_values.sol new file mode 100644 index 00000000..3acc8557 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_stray_values/library_stray_values.sol @@ -0,0 +1,11 @@ +library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } } +contract Test { + function f(uint x) public returns (uint) { + Lib; + Lib.m; + return x + 9; + } +} +// ---- +// library: Lib +// f(uint256): 33 -> 0x2a diff --git a/examples/test/semanticTests/libraries_library_stray_values/library_stray_values_standard_input.json b/examples/test/semanticTests/libraries_library_stray_values/library_stray_values_standard_input.json new file mode 100644 index 00000000..28efe351 --- /dev/null +++ b/examples/test/semanticTests/libraries_library_stray_values/library_stray_values_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression.sol b/examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression.sol new file mode 100644 index 00000000..96ee9bcf --- /dev/null +++ b/examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression.sol @@ -0,0 +1,16 @@ +library Arst { + struct Foo { + int256 Things; + int256 Stuff; + } +} + + +contract Tsra { + function f() public returns (uint256) { + Arst.Foo; + return 1; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression_standard_input.json b/examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression_standard_input.json new file mode 100644 index 00000000..7ac4d39c --- /dev/null +++ b/examples/test/semanticTests/libraries_library_struct_as_an_expression/library_struct_as_an_expression_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library.sol b/examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library.sol new file mode 100644 index 00000000..cfbf7b0c --- /dev/null +++ b/examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library.sol @@ -0,0 +1,38 @@ +library Lib { + function set(mapping(uint => uint) storage m, uint key, uint value) internal + { + m[key] = value; + } + function get(mapping(uint => uint) storage m, uint key) internal view returns (uint) + { + return m[key]; + } +} +contract Test { + mapping(uint => uint) m; + function set(uint256 key, uint256 value) public returns (uint) + { + uint oldValue = Lib.get(m, key); + Lib.set(m, key, value); + return oldValue; + } + function get(uint256 key) public view returns (uint) { + return Lib.get(m, key); + } +} +// ---- +// library: Lib +// set(uint256,uint256): 1, 42 -> 0 +// set(uint256,uint256): 2, 84 -> 0 +// set(uint256,uint256): 21, 7 -> 0 +// get(uint256): 0 -> 0 +// get(uint256): 1 -> 0x2a +// get(uint256): 2 -> 0x54 +// get(uint256): 21 -> 7 +// set(uint256,uint256): 1, 21 -> 0x2a +// set(uint256,uint256): 2, 42 -> 0x54 +// set(uint256,uint256): 21, 14 -> 7 +// get(uint256): 0 -> 0 +// get(uint256): 1 -> 0x15 +// get(uint256): 2 -> 0x2a +// get(uint256): 21 -> 14 diff --git a/examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library_standard_input.json b/examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library_standard_input.json new file mode 100644 index 00000000..8e71d485 --- /dev/null +++ b/examples/test/semanticTests/libraries_mapping_arguments_in_library/mapping_arguments_in_library_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library.sol b/examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library.sol new file mode 100644 index 00000000..da521f6b --- /dev/null +++ b/examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library.sol @@ -0,0 +1,72 @@ +library Lib { + function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage) + { + return c ? a : b; + } +} +contract Test { + mapping(uint => uint) a; + mapping(uint => uint) b; + function set(bool choice, uint256 key, uint256 value) public returns (uint) + { + mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice); + uint oldValue = m[key]; + m[key] = value; + return oldValue; + } + function get(bool choice, uint256 key) public view returns (uint) { + return Lib.choose_mapping(a, b, choice)[key]; + } + function get_a(uint256 key) public view returns (uint) { + return a[key]; + } + function get_b(uint256 key) public view returns (uint) { + return b[key]; + } +} +// ---- +// library: Lib +// set(bool,uint256,uint256): true, 1, 42 -> 0 +// set(bool,uint256,uint256): true, 2, 84 -> 0 +// set(bool,uint256,uint256): true, 21, 7 -> 0 +// set(bool,uint256,uint256): false, 1, 10 -> 0 +// set(bool,uint256,uint256): false, 2, 11 -> 0 +// set(bool,uint256,uint256): false, 21, 12 -> 0 +// get(bool,uint256): true, 0 -> 0 +// get(bool,uint256): true, 1 -> 0x2a +// get(bool,uint256): true, 2 -> 0x54 +// get(bool,uint256): true, 21 -> 7 +// get_a(uint256): 0 -> 0 +// get_a(uint256): 1 -> 0x2a +// get_a(uint256): 2 -> 0x54 +// get_a(uint256): 21 -> 7 +// get(bool,uint256): false, 0 -> 0 +// get(bool,uint256): false, 1 -> 10 +// get(bool,uint256): false, 2 -> 11 +// get(bool,uint256): false, 21 -> 12 +// get_b(uint256): 0 -> 0 +// get_b(uint256): 1 -> 10 +// get_b(uint256): 2 -> 11 +// get_b(uint256): 21 -> 12 +// set(bool,uint256,uint256): true, 1, 21 -> 0x2a +// set(bool,uint256,uint256): true, 2, 42 -> 0x54 +// set(bool,uint256,uint256): true, 21, 14 -> 7 +// set(bool,uint256,uint256): false, 1, 30 -> 10 +// set(bool,uint256,uint256): false, 2, 31 -> 11 +// set(bool,uint256,uint256): false, 21, 32 -> 12 +// get_a(uint256): 0 -> 0 +// get_a(uint256): 1 -> 0x15 +// get_a(uint256): 2 -> 0x2a +// get_a(uint256): 21 -> 14 +// get(bool,uint256): true, 0 -> 0 +// get(bool,uint256): true, 1 -> 0x15 +// get(bool,uint256): true, 2 -> 0x2a +// get(bool,uint256): true, 21 -> 14 +// get_b(uint256): 0 -> 0 +// get_b(uint256): 1 -> 0x1e +// get_b(uint256): 2 -> 0x1f +// get_b(uint256): 21 -> 0x20 +// get(bool,uint256): false, 0 -> 0 +// get(bool,uint256): false, 1 -> 0x1e +// get(bool,uint256): false, 2 -> 0x1f +// get(bool,uint256): false, 21 -> 0x20 diff --git a/examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library_standard_input.json b/examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library_standard_input.json new file mode 100644 index 00000000..92fe92cc --- /dev/null +++ b/examples/test/semanticTests/libraries_mapping_returns_in_library/mapping_returns_in_library_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named.sol b/examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named.sol new file mode 100644 index 00000000..e5963c1b --- /dev/null +++ b/examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named.sol @@ -0,0 +1,28 @@ +library Lib { + function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r) + { + r = a; + r[1] = 42; + r = b; + r[1] = 21; + } +} +contract Test { + mapping(uint => uint) a; + mapping(uint => uint) b; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.f(a, b)[2] = 84; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } + function g() public returns (uint, uint, uint, uint, uint, uint) + { + mapping(uint => uint) storage m = Lib.f(a, b); + m[2] = 17; + return (a[0], a[1], a[2], b[0], b[1], b[2]); + } +} +// ---- +// library: Lib +// f() -> 0, 0x2a, 0, 0, 0x15, 0x54 +// g() -> 0, 0x2a, 0, 0, 0x15, 0x11 diff --git a/examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named_standard_input.json b/examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named_standard_input.json new file mode 100644 index 00000000..daec8c2c --- /dev/null +++ b/examples/test/semanticTests/libraries_mapping_returns_in_library_named/mapping_returns_in_library_named_standard_input.json @@ -0,0 +1,214 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + }, + "internal_library_function_attached_to_literal.sol": { + "content": "library L {\n function double(uint a) internal pure returns (uint) {\n return a * 2;\n }\n\n function double(bytes memory a) internal pure returns (bytes memory) {\n return bytes.concat(a, a);\n }\n}\n\ncontract C {\n using L for *;\n\n function double42() public returns (uint) {\n return 42.double();\n }\n\n function doubleABC() public returns (bytes memory) {\n return \"abc\".double();\n }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n" + }, + "stub.sol": { + "content": "library L {\n function f(uint256 v) external returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// library: L\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "external_call_with_function_pointer_parameter.sol": { + "content": "library L {\n function run(\n function(uint256) external returns (uint256) _operation,\n uint256 _a\n )\n external\n returns (uint256)\n {\n return _operation(_a);\n }\n}\n\ncontract C {\n function double(uint256 _a) external returns (uint256) {\n return _a * _a;\n }\n\n function g(uint256 _value) external returns (uint256) {\n return L.run(this.double, _value);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "attached_public_library_function_accepting_calldata.sol.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) public pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "mapping_returns_in_library_named.sol": { + "content": "library Lib {\n function f(mapping(uint => uint) storage a, mapping(uint => uint) storage b) internal returns(mapping(uint=>uint) storage r)\n {\n r = a;\n r[1] = 42;\n r = b;\n r[1] = 21;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.f(a, b)[2] = 84;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n function g() public returns (uint, uint, uint, uint, uint, uint)\n {\n mapping(uint => uint) storage m = Lib.f(a, b);\n m[2] = 17;\n return (a[0], a[1], a[2], b[0], b[1], b[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 0, 0x2a, 0, 0, 0x15, 0x54\n// g() -> 0, 0x2a, 0, 0, 0x15, 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library.sol b/examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library.sol new file mode 100644 index 00000000..178f22b4 --- /dev/null +++ b/examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library.sol @@ -0,0 +1,11 @@ +library L { + function f() public returns (uint) { return 7; } +} +contract C { + function f() public payable returns (uint) { + return L.f(); + } +} +// ---- +// library: L +// f(): 27 -> 7 diff --git a/examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library_standard_input.json b/examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library_standard_input.json new file mode 100644 index 00000000..2f3fc3e1 --- /dev/null +++ b/examples/test/semanticTests/libraries_payable_function_calls_library/payable_function_calls_library_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_stub/stub.sol b/examples/test/semanticTests/libraries_stub/stub.sol new file mode 100644 index 00000000..8bae3df2 --- /dev/null +++ b/examples/test/semanticTests/libraries_stub/stub.sol @@ -0,0 +1,13 @@ +library L { + function f(uint256 v) external returns (uint256) { return v*v; } +} +contract C { + function g(uint256 v) external returns (uint256) { + return L.f(v); + } +} +// ---- +// library: L +// g(uint256): 1 -> 1 +// g(uint256): 2 -> 4 +// g(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/libraries_stub/stub_standard_input.json b/examples/test/semanticTests/libraries_stub/stub_standard_input.json new file mode 100644 index 00000000..c2bd0f8a --- /dev/null +++ b/examples/test/semanticTests/libraries_stub/stub_standard_input.json @@ -0,0 +1,205 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + }, + "internal_library_function_attached_to_enum.sol": { + "content": "library L {\n enum E { A, B }\n\n function equals(E a, E b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for L.E;\n\n function equalsA(uint choice) public returns (bool) {\n L.E x = L.E.A;\n return x.equals(L.E(choice));\n }\n}\n// ----\n// equalsA(uint256): 0 -> true\n// equalsA(uint256): 1 -> false\n" + }, + "mapping_returns_in_library.sol": { + "content": "library Lib {\n function choose_mapping(mapping(uint => uint) storage a, mapping(uint => uint) storage b, bool c) internal pure returns(mapping(uint=>uint) storage)\n {\n return c ? a : b;\n }\n}\ncontract Test {\n mapping(uint => uint) a;\n mapping(uint => uint) b;\n function set(bool choice, uint256 key, uint256 value) public returns (uint)\n {\n mapping(uint => uint) storage m = Lib.choose_mapping(a, b, choice);\n uint oldValue = m[key];\n m[key] = value;\n return oldValue;\n }\n function get(bool choice, uint256 key) public view returns (uint) {\n return Lib.choose_mapping(a, b, choice)[key];\n }\n function get_a(uint256 key) public view returns (uint) {\n return a[key];\n }\n function get_b(uint256 key) public view returns (uint) {\n return b[key];\n }\n}\n// ----\n// library: Lib\n// set(bool,uint256,uint256): true, 1, 42 -> 0\n// set(bool,uint256,uint256): true, 2, 84 -> 0\n// set(bool,uint256,uint256): true, 21, 7 -> 0\n// set(bool,uint256,uint256): false, 1, 10 -> 0\n// set(bool,uint256,uint256): false, 2, 11 -> 0\n// set(bool,uint256,uint256): false, 21, 12 -> 0\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x2a\n// get(bool,uint256): true, 2 -> 0x54\n// get(bool,uint256): true, 21 -> 7\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x2a\n// get_a(uint256): 2 -> 0x54\n// get_a(uint256): 21 -> 7\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 10\n// get(bool,uint256): false, 2 -> 11\n// get(bool,uint256): false, 21 -> 12\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 10\n// get_b(uint256): 2 -> 11\n// get_b(uint256): 21 -> 12\n// set(bool,uint256,uint256): true, 1, 21 -> 0x2a\n// set(bool,uint256,uint256): true, 2, 42 -> 0x54\n// set(bool,uint256,uint256): true, 21, 14 -> 7\n// set(bool,uint256,uint256): false, 1, 30 -> 10\n// set(bool,uint256,uint256): false, 2, 31 -> 11\n// set(bool,uint256,uint256): false, 21, 32 -> 12\n// get_a(uint256): 0 -> 0\n// get_a(uint256): 1 -> 0x15\n// get_a(uint256): 2 -> 0x2a\n// get_a(uint256): 21 -> 14\n// get(bool,uint256): true, 0 -> 0\n// get(bool,uint256): true, 1 -> 0x15\n// get(bool,uint256): true, 2 -> 0x2a\n// get(bool,uint256): true, 21 -> 14\n// get_b(uint256): 0 -> 0\n// get_b(uint256): 1 -> 0x1e\n// get_b(uint256): 2 -> 0x1f\n// get_b(uint256): 21 -> 0x20\n// get(bool,uint256): false, 0 -> 0\n// get(bool,uint256): false, 1 -> 0x1e\n// get(bool,uint256): false, 2 -> 0x1f\n// get(bool,uint256): false, 21 -> 0x20\n" + }, + "internal_library_function_attached_to_bool.sol": { + "content": "library L {\n function xor(bool a, bool b) internal pure returns (bool) {\n return a != b;\n }\n}\n\ncontract C {\n using L for bool;\n\n function foo(bool a, bool b) public returns (bool) {\n return a.xor(b);\n }\n}\n// ----\n// foo(bool,bool): true, true -> false\n// foo(bool,bool): true, false -> true\n// foo(bool,bool): false, true -> true\n// foo(bool,bool): false, false -> false\n" + }, + "internal_library_function_attached_to_interface.sol": { + "content": "interface I {}\ncontract E is I {}\n\nlibrary L {\n function foo(I i) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for I;\n\n function test() public returns (uint) {\n E e = new E();\n return I(e).foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_calling_private.sol": { + "content": "// tests that internal library functions that are called from outside and that\n// themselves call private functions are still able to (i.e. the private function\n// also has to be pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function g(uint256[] memory _data) private {\n _data[3] = 2;\n }\n\n function f(uint256[] memory _data) internal {\n g(_data);\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_delegatecall_guard_view_staticcall.sol": { + "content": "contract D {\n uint public x;\n constructor() { x = 42; }\n}\nlibrary L {\n function f(D d) public view returns (uint256) {\n return d.x();\n }\n}\ncontract C {\n D d;\n constructor() { d = new D(); }\n function f() public view returns (uint256) {\n return L.f(d);\n }\n function g() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, d));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 42\n// g() -> true, 42\n// h() -> true, 42\n" + }, + "attached_public_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) public pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) public pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: D\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "internal_library_function_attached_to_integer.sol": { + "content": "library L {\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n}\n\ncontract C {\n using L for uint256;\n\n function foo(uint256 a, uint256 b) public returns (uint256) {\n return a.add(b);\n }\n}\n// ----\n// foo(uint256,uint256): 8, 42 -> 50\n" + }, + "library_address_via_module.sol": { + "content": "==== Source: a.sol ====\n\nimport \"a.sol\" as M;\n\nlibrary L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(M.L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return M.L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(M.L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: \"a.sol\":L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "external_call_with_storage_array_parameter.sol": { + "content": "library L {\n function f(uint256[2] storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n uint256[2] x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function_pointer.sol": { + "content": "library L {\n function f() internal returns (uint) {\n return 66;\n }\n}\n\ncontract C {\n function g() public returns (uint) {\n function() internal returns(uint) ptr;\n ptr = L.f;\n return ptr();\n }\n}\n// ----\n// g() -> 66\n" + }, + "library_staticcall_delegatecall.sol": { + "content": "library Lib {\n function x() public view returns (uint) {\n return 1;\n }\n}\ncontract Test {\n uint t;\n function f() public returns (uint) {\n t = 2;\n return this.g();\n }\n function g() public view returns (uint) {\n return Lib.x();\n }\n}\n// ----\n// library: Lib\n// f() -> 1\n" + }, + "internal_library_function_attached_to_dynamic_array.sol": { + "content": "library L {\n function at(uint[] memory a, uint i) internal pure returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for uint[];\n\n function secondItem() public returns (uint) {\n uint[] memory input = new uint[](2);\n input[0] = 0x11;\n input[1] = 0x22;\n\n return input.at(1);\n }\n}\n// ----\n// secondItem() -> 0x22\n" + }, + "internal_library_function_attached_to_literal.sol": { + "content": "library L {\n function double(uint a) internal pure returns (uint) {\n return a * 2;\n }\n\n function double(bytes memory a) internal pure returns (bytes memory) {\n return bytes.concat(a, a);\n }\n}\n\ncontract C {\n using L for *;\n\n function double42() public returns (uint) {\n return 42.double();\n }\n\n function doubleABC() public returns (bytes memory) {\n return \"abc\".double();\n }\n}\n// ----\n// double42() -> 84\n// doubleABC() -> 0x20, 6, \"abcabc\"\n" + }, + "stub.sol": { + "content": "library L {\n function f(uint256 v) external returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// library: L\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_stub_internal/stub_internal.sol b/examples/test/semanticTests/libraries_stub_internal/stub_internal.sol new file mode 100644 index 00000000..075b8dbb --- /dev/null +++ b/examples/test/semanticTests/libraries_stub_internal/stub_internal.sol @@ -0,0 +1,12 @@ +library L { + function f(uint256 v) internal returns (uint256) { return v*v; } +} +contract C { + function g(uint256 v) external returns (uint256) { + return L.f(v); + } +} +// ---- +// g(uint256): 1 -> 1 +// g(uint256): 2 -> 4 +// g(uint256): 4 -> 16 diff --git a/examples/test/semanticTests/libraries_stub_internal/stub_internal_standard_input.json b/examples/test/semanticTests/libraries_stub_internal/stub_internal_standard_input.json new file mode 100644 index 00000000..04a35737 --- /dev/null +++ b/examples/test/semanticTests/libraries_stub_internal/stub_internal_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name.sol b/examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name.sol new file mode 100644 index 00000000..d6c7f313 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name.sol @@ -0,0 +1,13 @@ +library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 6; + return x.mul({x: a}); + } +} +// ---- +// library: D +// f(uint256): 7 -> 0x2a +// x() -> 0x2a diff --git a/examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name_standard_input.json b/examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name_standard_input.json new file mode 100644 index 00000000..5e917fb7 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_by_name/using_for_by_name_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int.sol b/examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int.sol new file mode 100644 index 00000000..f44da5a8 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int.sol @@ -0,0 +1,12 @@ +library D { + function double(uint self) public returns (uint) { return 2 * self; } +} +contract C { + using D for uint; + function f(uint a) public returns (uint) { + return a.double(); + } +} +// ---- +// library: D +// f(uint256): 9 -> 18 diff --git a/examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int_standard_input.json b/examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int_standard_input.json new file mode 100644 index 00000000..c4b79ad3 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_function_on_int/using_for_function_on_int_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_for_overload/using_for_overload.sol b/examples/test/semanticTests/libraries_using_for_overload/using_for_overload.sol new file mode 100644 index 00000000..5dd67fba --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_overload/using_for_overload.sol @@ -0,0 +1,17 @@ +library D { + struct s { uint a; } + function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } + function mul(s storage self, bytes32 x) public returns (bytes32) { } +} +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 6; + return x.mul(a); + } +} +// ---- +// library: D +// f(uint256): 7 -> 0x2a +// x() -> 0x2a diff --git a/examples/test/semanticTests/libraries_using_for_overload/using_for_overload_standard_input.json b/examples/test/semanticTests/libraries_using_for_overload/using_for_overload_standard_input.json new file mode 100644 index 00000000..ff7d568c --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_overload/using_for_overload_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs.sol b/examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs.sol new file mode 100644 index 00000000..cd45726b --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs.sol @@ -0,0 +1,25 @@ +struct Struct { uint x; } + +library L { + function f(Struct storage _x) internal view returns (uint256) { + return _x.x; + } +} + +contract C { + using L for Struct; + + Struct s; + + function h(Struct storage _s) internal view returns (uint) { + // _s is pointer + return _s.f(); + } + function g() public returns (uint, uint) { + s.x = 7; + // s is reference + return (s.f(), h(s)); + } +} +// ---- +// g() -> 7, 7 diff --git a/examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs_standard_input.json b/examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs_standard_input.json new file mode 100644 index 00000000..7750a18b --- /dev/null +++ b/examples/test/semanticTests/libraries_using_for_storage_structs/using_for_storage_structs_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public.sol b/examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public.sol new file mode 100644 index 00000000..17406a90 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public.sol @@ -0,0 +1,24 @@ +library Lib { + function set(mapping(uint => uint) storage m, uint key, uint value) public + { + m[key] = value; + } +} +contract Test { + mapping(uint => uint) m1; + mapping(uint => uint) m2; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.set(m1, 0, 1); + Lib.set(m1, 2, 42); + Lib.set(m2, 0, 23); + Lib.set(m2, 2, 99); + return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]); + } +} +// ---- +// library: Lib +// f() -> 1, 0, 0x2a, 0x17, 0, 0x63 +// gas irOptimized: 119837 +// gas legacy: 124661 +// gas legacyOptimized: 119665 diff --git a/examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public_standard_input.json b/examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public_standard_input.json new file mode 100644 index 00000000..500c4a06 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_library_mappings_public/using_library_mappings_public_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return.sol b/examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return.sol new file mode 100644 index 00000000..6e852fdc --- /dev/null +++ b/examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return.sol @@ -0,0 +1,22 @@ +library Lib { + function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) { + return m[key]; + } +} +contract Test { + mapping(uint => mapping(uint => uint)) m; + function f() public returns (uint, uint, uint, uint, uint, uint) + { + Lib.choose(m, 0)[0] = 1; + Lib.choose(m, 0)[2] = 42; + Lib.choose(m, 1)[0] = 23; + Lib.choose(m, 1)[2] = 99; + return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]); + } +} +// ---- +// library: Lib +// f() -> 1, 0, 0x2a, 0x17, 0, 0x63 +// gas irOptimized: 119568 +// gas legacy: 125087 +// gas legacyOptimized: 120120 diff --git a/examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return_standard_input.json b/examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return_standard_input.json new file mode 100644 index 00000000..93ca080c --- /dev/null +++ b/examples/test/semanticTests/libraries_using_library_mappings_return/using_library_mappings_return_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/libraries_using_library_structs/using_library_structs.sol b/examples/test/semanticTests/libraries_using_library_structs/using_library_structs.sol new file mode 100644 index 00000000..c2ecf103 --- /dev/null +++ b/examples/test/semanticTests/libraries_using_library_structs/using_library_structs.sol @@ -0,0 +1,24 @@ +library Lib { + struct Data { uint a; uint[] b; } + function set(Data storage _s) public + { + _s.a = 7; + while (_s.b.length < 20) + _s.b.push(); + _s.b[19] = 8; + } +} +contract Test { + mapping(string => Lib.Data) data; + function f() public returns (uint a, uint b) + { + Lib.set(data["abc"]); + a = data["abc"].a; + b = data["abc"].b[19]; + } +} +// ---- +// library: Lib +// f() -> 7, 8 +// gas irOptimized: 101818 +// gas legacy: 101428 diff --git a/examples/test/semanticTests/libraries_using_library_structs/using_library_structs_standard_input.json b/examples/test/semanticTests/libraries_using_library_structs/using_library_structs_standard_input.json new file mode 100644 index 00000000..fac8167c --- /dev/null +++ b/examples/test/semanticTests/libraries_using_library_structs/using_library_structs_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "internal_library_function_attached_to_fixed_bytes.sol": { + "content": "library L {\n function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {\n return bytes2(uint16(a) + uint16(b));\n }\n}\n\ncontract C {\n using L for bytes2;\n\n function sum(bytes2 a, bytes2 b) public returns (bytes2) {\n return a.add(b);\n }\n}\n// ----\n// sum(bytes2,bytes2): left(0x1100), left(0x0022) -> left(0x1122)\n" + }, + "using_for_storage_structs.sol": { + "content": "struct Struct { uint x; }\n\nlibrary L {\n function f(Struct storage _x) internal view returns (uint256) {\n return _x.x;\n }\n}\n\ncontract C {\n using L for Struct;\n\n Struct s;\n\n function h(Struct storage _s) internal view returns (uint) {\n // _s is pointer\n return _s.f();\n }\n function g() public returns (uint, uint) {\n s.x = 7;\n // s is reference\n return (s.f(), h(s));\n }\n}\n// ----\n// g() -> 7, 7\n" + }, + "payable_function_calls_library.sol": { + "content": "library L {\n function f() public returns (uint) { return 7; }\n}\ncontract C {\n function f() public payable returns (uint) {\n return L.f();\n }\n}\n// ----\n// library: L\n// f(): 27 -> 7\n" + }, + "internal_call_unattached_with_parentheses.sol": { + "content": "library L {\n\tfunction f() internal returns (uint) {\n\t\treturn 3;\n\t}\n}\n\ncontract C {\n\tfunction foo() public returns (uint) {\n\t\treturn (L.f)();\n\t}\n}\n// ----\n// foo() -> 3\n" + }, + "internal_library_function_attached_to_internal_function_type.sol": { + "content": "library L {\n function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "attached_internal_library_function_accepting_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes1) {\n return _x[0];\n }\n function g(bytes memory _x) internal pure returns (bytes1) {\n return _x[0];\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f(), _x.g());\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_function_selectors_struct.sol": { + "content": "pragma abicoder v2;\nlibrary L {\n struct S { uint256 a; }\n function f(S storage s) external returns (uint) { return s.a; }\n function g(S memory m) public returns (uint) { return m.a; }\n}\ncontract C {\n L.S s;\n constructor() { s.a = 42; }\n\n function f() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, s_ptr));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(L.S storage)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, L.S(23)));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(L.S)\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 42\n// g() -> true, true, 23\n" + }, + "library_enum_as_an_expression.sol": { + "content": "library Arst {\n enum Foo {Things, Stuff}\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "internal_library_function_attached_to_string_accepting_memory.sol": { + "content": "library L {\n function at(string memory a, uint i) internal pure returns (uint8) {\n return uint8(bytes(a)[i]);\n }\n}\n\ncontract C {\n using L for string;\n\n function secondChar() public returns (uint8) {\n string memory input = \"abc\";\n return input.at(1);\n }\n}\n// ----\n// secondChar() -> 98\n" + }, + "using_library_mappings_return.sol": { + "content": "library Lib {\n function choose(mapping(uint => mapping(uint => uint)) storage m, uint key) external returns (mapping(uint => uint) storage) {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => mapping(uint => uint)) m;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.choose(m, 0)[0] = 1;\n Lib.choose(m, 0)[2] = 42;\n Lib.choose(m, 1)[0] = 23;\n Lib.choose(m, 1)[2] = 99;\n return (m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119568\n// gas legacy: 125087\n// gas legacyOptimized: 120120\n" + }, + "library_delegatecall_guard_view_not_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return 84;\n }\n}\ncontract C {\n uint256[] y;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 84\n// g() -> true, 84\n// h() -> true, 84\n" + }, + "external_call_with_storage_mapping_parameter.sol": { + "content": "library L {\n function f(mapping(uint256 => uint256) storage _a) external returns (uint256) {\n return _a[0] * _a[1];\n }\n}\n\ncontract C {\n mapping(uint256 => uint256) x;\n\n function g(uint256 _value) external returns (uint256) {\n x[0] = x[1] = _value;\n return L.f(x);\n }\n}\n// ----\n// library: L\n// g(uint256): 4 -> 16\n" + }, + "internal_library_function.sol": { + "content": "// tests that internal library functions can be called from outside\n// and retain the same memory context (i.e. are pulled into the caller's code)\n// This has to work without linking, because everything will be inlined.\nlibrary L {\n function f(uint256[] memory _data) internal {\n _data[3] = 2;\n }\n}\n\n\ncontract C {\n function f() public returns (uint256) {\n uint256[] memory x = new uint256[](7);\n x[3] = 8;\n L.f(x);\n return x[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_return_struct_with_mapping.sol": { + "content": "pragma abicoder v2;\n\nlibrary Lib {\n struct Items {\n mapping (uint => uint) a;\n }\n\n function get() public returns (Items storage x) {\n assembly { x.slot := 123 }\n }\n}\n\ncontract C {\n function f() public returns(uint256 slot) {\n Lib.Items storage ptr = Lib.get();\n assembly { slot := ptr.slot }\n }\n}\n// ----\n// library: Lib\n// f() -> 123\n" + }, + "stub_internal.sol": { + "content": "library L {\n function f(uint256 v) internal returns (uint256) { return v*v; }\n}\ncontract C {\n function g(uint256 v) external returns (uint256) {\n return L.f(v);\n }\n}\n// ----\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n" + }, + "using_for_overload.sol": { + "content": "library D {\n struct s { uint a; }\n function mul(s storage self, uint x) public returns (uint) { return self.a *= x; }\n function mul(s storage self, bytes32 x) public returns (bytes32) { }\n}\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_return_var_size.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal returns (uint256[] memory) {\n _s.data[3] = 2;\n return _s.data;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n return x.f()[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "library_stray_values.sol": { + "content": "library Lib { function m(uint x, uint y) public returns (uint) { return x * y; } }\ncontract Test {\n function f(uint x) public returns (uint) {\n Lib;\n Lib.m;\n return x + 9;\n }\n}\n// ----\n// library: Lib\n// f(uint256): 33 -> 0x2a\n" + }, + "library_references_preserve.sol": { + "content": "library L1 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 1;\n }\n}\n\nlibrary L2 {\n function add(uint256 a, uint256 b) external pure returns (uint256) {\n return a + b + 2;\n }\n}\n\ncontract A {\n uint256 sum;\n constructor() {\n sum = L1.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract B {\n uint256 sum;\n constructor() {\n sum = L2.add(1, 2);\n }\n function getSum() external view returns(uint256) {\n return sum;\n }\n}\n\ncontract C {\n A a = new A();\n B b = new B();\n function aSum() external view returns(uint256) {\n return a.getSum();\n }\n function bSum() external view returns(uint256) {\n return b.getSum();\n }\n}\n// ----\n// library: L1\n// library: L2\n// aSum() -> 4\n// bSum() -> 5\n" + }, + "library_call_in_homestead.sol": { + "content": "library Lib { function m() public returns (address) { return msg.sender; } }\ncontract Test {\n address public sender;\n function f() public {\n sender = Lib.m();\n }\n}\n// ====\n// EVMVersion: >=homestead\n// ----\n// library: Lib\n// f() ->\n// sender() -> 0x1212121212121212121212121212120000000012\n" + }, + "library_function_selectors.sol": { + "content": "library L {\n function f(uint256 x) external returns (uint) { return x; }\n function g(uint256[] storage s) external returns (uint) { return s.length; }\n function h(uint256[] memory m) public returns (uint) { return m.length; }\n}\ncontract C {\n uint256[] s;\n constructor() { while (s.length < 42) s.push(0); }\n function f() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, 7));\n\t\treturn (L.f.selector == bytes4(keccak256(\"f(uint256)\")), success, abi.decode(data, (uint256)));\n }\n function g() public returns (bool, bool, uint256) {\n\t\tuint256 s_ptr;\n\t\tassembly { s_ptr := s.slot }\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.g.selector, s_ptr));\n\t\treturn (L.g.selector == bytes4(keccak256(\"g(uint256[] storage)\")), success, abi.decode(data, (uint256)));\n }\n function h() public returns (bool, bool, uint256) {\n\t\t(bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.h.selector, new uint256[](23)));\n\t\treturn (L.h.selector == bytes4(keccak256(\"h(uint256[])\")), success, abi.decode(data, (uint256)));\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> true, true, 7\n// g() -> true, true, 42\n// h() -> true, true, 23\n" + }, + "library_address.sol": { + "content": "library L {\n function f(uint256 v) external pure returns (uint) {\n return v * v;\n }\n function g(uint256 v) external returns (uint) {\n return v * v;\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 v) public view returns (uint256) {\n return L.f(v);\n }\n function h(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function i(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"f(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function j(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).delegatecall(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n function k(uint256 v) public returns (uint256) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g(uint256)\", v));\n assert(success);\n return abi.decode(result, (uint256));\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// addr() -> false\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 4\n// g(uint256): 4 -> 16\n// h(uint256): 1 -> 1\n// h(uint256): 2 -> 4\n// h(uint256): 4 -> 16\n// i(uint256): 1 -> 1\n// i(uint256): 2 -> 4\n// i(uint256): 4 -> 16\n// j(uint256): 1 -> 1\n// j(uint256): 2 -> 4\n// j(uint256): 4 -> 16\n// k(uint256): 1 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x01\n// k(uint256): 4 -> FAILURE, hex\"4e487b71\", 0x01\n" + }, + "using_library_mappings_public.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) public\n {\n m[key] = value;\n }\n}\ncontract Test {\n mapping(uint => uint) m1;\n mapping(uint => uint) m2;\n function f() public returns (uint, uint, uint, uint, uint, uint)\n {\n Lib.set(m1, 0, 1);\n Lib.set(m1, 2, 42);\n Lib.set(m2, 0, 23);\n Lib.set(m2, 2, 99);\n return (m1[0], m1[1], m1[2], m2[0], m2[1], m2[2]);\n }\n}\n// ----\n// library: Lib\n// f() -> 1, 0, 0x2a, 0x17, 0, 0x63\n// gas irOptimized: 119837\n// gas legacy: 124661\n// gas legacyOptimized: 119665\n" + }, + "internal_library_function_attached_to_external_function_type.sol": { + "content": "library L {\n // NOTE: External function takes up two stack slots\n function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) external pure returns (uint);\n\n function identity(uint x) external pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return this.identity.double(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "internal_library_function_attached_to_contract.sol": { + "content": "contract E {}\n\nlibrary L {\n function foo(E e) internal pure returns (uint) {\n return 42;\n }\n}\n\ncontract C {\n using L for E;\n\n function test() public returns (uint) {\n E e = new E();\n return e.foo();\n }\n}\n// ----\n// test() -> 42\n" + }, + "internal_library_function_attached_to_mapping.sol": { + "content": "library L {\n function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {\n return a[i];\n }\n}\n\ncontract C {\n using L for mapping(uint => uint);\n\n mapping(uint => uint) map;\n\n function mapValue(uint a) public returns (uint) {\n map[42] = 0x24;\n map[66] = 0x66;\n\n return map.at(a);\n }\n}\n// ----\n// mapValue(uint256): 42 -> 0x24\n" + }, + "internal_library_function_attached_to_address_named_send_transfer.sol": { + "content": "library L {\n function transfer(address a) internal {}\n function send(address a) internal {}\n}\n\ncontract C {\n using L for address;\n\n function useTransfer(address a) public {\n a.transfer();\n }\n\n function useSend(address a) public {\n a.send();\n }\n}\n// ----\n// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->\n// useSend(address): 0x111122223333444455556666777788889999aAaa ->\n" + }, + "library_delegatecall_guard_view_needed.sol": { + "content": "library L {\n function f(uint256[] storage x) public view returns (uint256) {\n return x.length;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 1\n// g() -> true, 1\n// h() -> true, 0 # this is bad - this should fail! #\n" + }, + "internal_library_function_attached_to_string_accepting_storage.sol": { + "content": "library L {\n function f(string memory a) internal pure returns (string memory) {\n return a;\n }\n function g(string storage a) internal pure returns (string memory) {\n return a;\n }\n}\n\ncontract C {\n using L for string;\n string s;\n\n function test(string calldata x) public returns (string memory, string memory) {\n s = x;\n return (s.f(), s.g());\n }\n}\n// ----\n// test(string): 0x20, 3, \"def\" -> 0x40, 0x80, 3, \"def\", 3, \"def\"\n" + }, + "using_for_function_on_int.sol": { + "content": "library D {\n\tfunction double(uint self) public returns (uint) { return 2 * self; }\n}\ncontract C {\n\tusing D for uint;\n\tfunction f(uint a) public returns (uint) {\n\t\treturn a.double();\n\t}\n}\n// ----\n// library: D\n// f(uint256): 9 -> 18\n" + }, + "internal_call_attached_with_parentheses.sol": { + "content": "library L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] += 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n (x.f)();\n return x.data[3];\n }\n}\n// ----\n// f() -> 0x0a\n" + }, + "internal_library_function_attached_to_address.sol": { + "content": "library L {\n function equals(address a, address b) internal pure returns (bool) {\n return a == b;\n }\n}\n\ncontract C {\n using L for address;\n\n function foo(address a, address b) public returns (bool) {\n return a.equals(b);\n }\n}\n// ----\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true\n// foo(address,address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false\n" + }, + "attached_internal_library_function_returning_calldata.sol": { + "content": "library D {\n function f(bytes calldata _x) internal pure returns (bytes calldata) {\n return _x;\n }\n function g(bytes calldata _x) internal pure returns (bytes memory) {\n return _x;\n }\n}\n\ncontract C {\n using D for bytes;\n function f(bytes calldata _x) public pure returns (bytes1, bytes1) {\n return (_x.f()[0], _x.g()[0]);\n }\n}\n// ----\n// f(bytes): 0x20, 4, \"abcd\" -> 0x6100000000000000000000000000000000000000000000000000000000000000, 0x6100000000000000000000000000000000000000000000000000000000000000\n" + }, + "library_struct_as_an_expression.sol": { + "content": "library Arst {\n struct Foo {\n int256 Things;\n int256 Stuff;\n }\n}\n\n\ncontract Tsra {\n function f() public returns (uint256) {\n Arst.Foo;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "library_delegatecall_guard_pure.sol": { + "content": "library L {\n function f(uint256[] storage x) public pure returns (uint256) {\n return 23;\n }\n}\ncontract C {\n uint256[] y;\n string x;\n constructor() { y.push(42); }\n function f() public view returns (uint256) {\n return L.f(y);\n }\n function g() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).delegatecall(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n function h() public returns (bool, uint256) {\n uint256 ys;\n assembly { ys := y.slot }\n (bool success, bytes memory data) = address(L).call(abi.encodeWithSelector(L.f.selector, ys));\n return (success, success ? abi.decode(data,(uint256)) : 0);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// library: L\n// f() -> 23\n// g() -> true, 23\n// h() -> true, 23\n" + }, + "mapping_arguments_in_library.sol": { + "content": "library Lib {\n function set(mapping(uint => uint) storage m, uint key, uint value) internal\n {\n m[key] = value;\n }\n function get(mapping(uint => uint) storage m, uint key) internal view returns (uint)\n {\n return m[key];\n }\n}\ncontract Test {\n mapping(uint => uint) m;\n function set(uint256 key, uint256 value) public returns (uint)\n {\n uint oldValue = Lib.get(m, key);\n Lib.set(m, key, value);\n return oldValue;\n }\n function get(uint256 key) public view returns (uint) {\n return Lib.get(m, key);\n }\n}\n// ----\n// library: Lib\n// set(uint256,uint256): 1, 42 -> 0\n// set(uint256,uint256): 2, 84 -> 0\n// set(uint256,uint256): 21, 7 -> 0\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x2a\n// get(uint256): 2 -> 0x54\n// get(uint256): 21 -> 7\n// set(uint256,uint256): 1, 21 -> 0x2a\n// set(uint256,uint256): 2, 42 -> 0x54\n// set(uint256,uint256): 21, 14 -> 7\n// get(uint256): 0 -> 0\n// get(uint256): 1 -> 0x15\n// get(uint256): 2 -> 0x2a\n// get(uint256): 21 -> 14\n" + }, + "using_for_by_name.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 6;\n return x.mul({x: a});\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x2a\n// x() -> 0x2a\n" + }, + "internal_library_function_attached_to_internal_function_type_named_selector.sol": { + "content": "library L {\n function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {\n return f(x) * 2;\n }\n}\n\ncontract C {\n using L for function(uint) internal pure returns (uint);\n\n function identity(uint x) internal pure returns (uint) {\n return x;\n }\n\n function test(uint value) public returns (uint) {\n return identity.selector(value);\n }\n}\n// ----\n// test(uint256): 5 -> 10\n" + }, + "library_address_homestead.sol": { + "content": "library L {\n function f(uint256 a, uint256 b) external {\n assert(a * a == b);\n }\n}\ncontract C {\n function addr() public view returns (bool) {\n return address(L) == address(0);\n }\n function g(uint256 a, uint256 b) public returns (bool) {\n (bool success,) = address(L).delegatecall(abi.encodeWithSignature(\"f(uint256,uint256)\", a, b));\n return success;\n }\n}\n// ----\n// library: L\n// g(uint256,uint256): 1, 1 -> true\n// g(uint256,uint256): 1, 2 -> false\n// g(uint256,uint256): 2, 3 -> false\n// g(uint256,uint256): 2, 4 -> true\n// g(uint256,uint256): 2, 5 -> false\n// g(uint256,uint256): 4, 15 -> false\n// g(uint256,uint256): 4, 16 -> true\n// g(uint256,uint256): 4, 17 -> false\n" + }, + "internal_library_function_attached_to_array_named_pop_push.sol": { + "content": "library L {\n function pop(uint[2] memory a) internal {}\n function push(uint[2] memory a) internal {}\n}\n\ncontract C {\n using L for uint[2];\n\n function test() public {\n uint[2] memory input;\n\n input.push();\n input.pop();\n }\n}\n// ----\n// test() ->\n" + }, + "internal_types_in_library.sol": { + "content": "library Lib {\n function find(uint16[] storage _haystack, uint16 _needle) public view returns (uint)\n {\n for (uint i = 0; i < _haystack.length; ++i)\n if (_haystack[i] == _needle)\n return i;\n return type(uint).max;\n }\n}\ncontract Test {\n mapping(string => uint16[]) data;\n function f() public returns (uint a, uint b)\n {\n while (data[\"abc\"].length < 20)\n data[\"abc\"].push();\n data[\"abc\"][4] = 9;\n data[\"abc\"][17] = 3;\n a = Lib.find(data[\"abc\"], 9);\n b = Lib.find(data[\"abc\"], 3);\n }\n}\n// ----\n// library: Lib\n// f() -> 4, 0x11\n// gas irOptimized: 111419\n// gas legacy: 132930\n// gas legacyOptimized: 118020\n" + }, + "internal_library_function_attached_to_struct.sol": { + "content": "// This has to work without linking, because everything will be inlined.\nlibrary L {\n struct S {\n uint256[] data;\n }\n\n function f(S memory _s) internal {\n _s.data[3] = 2;\n }\n}\n\n\ncontract C {\n using L for L.S;\n\n function f() public returns (uint256) {\n L.S memory x;\n x.data = new uint256[](7);\n x.data[3] = 8;\n x.f();\n return x.data[3];\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_library_structs.sol": { + "content": "library Lib {\n struct Data { uint a; uint[] b; }\n function set(Data storage _s) public\n {\n _s.a = 7;\n while (_s.b.length < 20)\n _s.b.push();\n _s.b[19] = 8;\n }\n}\ncontract Test {\n mapping(string => Lib.Data) data;\n function f() public returns (uint a, uint b)\n {\n Lib.set(data[\"abc\"]);\n a = data[\"abc\"].a;\n b = data[\"abc\"].b[19];\n }\n}\n// ----\n// library: Lib\n// f() -> 7, 8\n// gas irOptimized: 101818\n// gas legacy: 101428\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_denominations/denominations.sol b/examples/test/semanticTests/literals_denominations/denominations.sol new file mode 100644 index 00000000..f423775a --- /dev/null +++ b/examples/test/semanticTests/literals_denominations/denominations.sol @@ -0,0 +1,7 @@ +contract C { + uint constant x = 1 ether + 1 gwei + 1 wei; + + function f() public view returns(uint) { return x; } +} +// ---- +// f() -> 1000000001000000001 diff --git a/examples/test/semanticTests/literals_denominations/denominations_standard_input.json b/examples/test/semanticTests/literals_denominations/denominations_standard_input.json new file mode 100644 index 00000000..e1fc2a23 --- /dev/null +++ b/examples/test/semanticTests/literals_denominations/denominations_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes.sol b/examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes.sol new file mode 100644 index 00000000..43a09af0 --- /dev/null +++ b/examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes.sol @@ -0,0 +1,25 @@ +contract C { + uint[2 wei] a; + uint[2 gwei] b; + uint[2 ether] c; + uint[2 seconds] d; + uint[2 minutes] e; + uint[2 hours] f; + uint[2 days] g; + uint[2 weeks] h; + + function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) { + return ( + a.length, + b.length, + c.length, + d.length, + e.length, + f.length, + g.length, + h.length + ); + } +} +// ---- +// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600 diff --git a/examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes_standard_input.json b/examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes_standard_input.json new file mode 100644 index 00000000..6d77063a --- /dev/null +++ b/examples/test/semanticTests/literals_denominations_in_array_sizes/denominations_in_array_sizes_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_escape/escape.sol b/examples/test/semanticTests/literals_escape/escape.sol new file mode 100644 index 00000000..96fa9b11 --- /dev/null +++ b/examples/test/semanticTests/literals_escape/escape.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; + +contract C +{ + function f() public pure returns (uint, bytes1, bytes1) { + bytes memory encoded = abi.encodePacked("\\\\"); + return (encoded.length, encoded[0], encoded[1]); + } +} +// ---- +// f() -> 2, 0x5c00000000000000000000000000000000000000000000000000000000000000, 0x5c00000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/literals_escape/escape_standard_input.json b/examples/test/semanticTests/literals_escape/escape_standard_input.json new file mode 100644 index 00000000..4dff5bb5 --- /dev/null +++ b/examples/test/semanticTests/literals_escape/escape_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + }, + "scientific_notation.sol": { + "content": "contract C {\n function f() public returns(uint) {\n return 2e10 wei;\n }\n\n function g() public returns(uint) {\n return 200e-2 wei;\n }\n\n function h() public returns(uint) {\n return 2.5e1;\n }\n\n function i() public returns(int) {\n return -2e10;\n }\n\n function j() public returns(int) {\n return -200e-2;\n }\n\n function k() public returns(int) {\n return -2.5e1;\n }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n" + }, + "fractional_denominations.sol": { + "content": "contract C {\n uint public g = 1.5 gwei;\n uint public e = 1.5 ether;\n uint public m = 1.5 minutes;\n uint public h = 1.5 hours;\n uint public d = 1.5 days;\n uint public w = 1.5 weeks;\n}\n// ----\n// g() -> 1500000000\n// e() -> 1500000000000000000\n// m() -> 90\n// h() -> 5400\n// d() -> 129600\n// w() -> 907200\n" + }, + "escape.sol": { + "content": "pragma abicoder v2;\n\ncontract C\n{\n\tfunction f() public pure returns (uint, bytes1, bytes1) {\n\t\tbytes memory encoded = abi.encodePacked(\"\\\\\\\\\");\n\t\treturn (encoded.length, encoded[0], encoded[1]);\n\t}\n}\n// ----\n// f() -> 2, 0x5c00000000000000000000000000000000000000000000000000000000000000, 0x5c00000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_ether/ether.sol b/examples/test/semanticTests/literals_ether/ether.sol new file mode 100644 index 00000000..16cb7531 --- /dev/null +++ b/examples/test/semanticTests/literals_ether/ether.sol @@ -0,0 +1,7 @@ +contract C { + uint constant x = 1 ether; + + function f() public view returns(uint) { return x; } +} +// ---- +// f() -> 1000000000000000000 diff --git a/examples/test/semanticTests/literals_ether/ether_standard_input.json b/examples/test/semanticTests/literals_ether/ether_standard_input.json new file mode 100644 index 00000000..66b469ff --- /dev/null +++ b/examples/test/semanticTests/literals_ether/ether_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + }, + "scientific_notation.sol": { + "content": "contract C {\n function f() public returns(uint) {\n return 2e10 wei;\n }\n\n function g() public returns(uint) {\n return 200e-2 wei;\n }\n\n function h() public returns(uint) {\n return 2.5e1;\n }\n\n function i() public returns(int) {\n return -2e10;\n }\n\n function j() public returns(int) {\n return -200e-2;\n }\n\n function k() public returns(int) {\n return -2.5e1;\n }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n" + }, + "fractional_denominations.sol": { + "content": "contract C {\n uint public g = 1.5 gwei;\n uint public e = 1.5 ether;\n uint public m = 1.5 minutes;\n uint public h = 1.5 hours;\n uint public d = 1.5 days;\n uint public w = 1.5 weeks;\n}\n// ----\n// g() -> 1500000000\n// e() -> 1500000000000000000\n// m() -> 90\n// h() -> 5400\n// d() -> 129600\n// w() -> 907200\n" + }, + "escape.sol": { + "content": "pragma abicoder v2;\n\ncontract C\n{\n\tfunction f() public pure returns (uint, bytes1, bytes1) {\n\t\tbytes memory encoded = abi.encodePacked(\"\\\\\\\\\");\n\t\treturn (encoded.length, encoded[0], encoded[1]);\n\t}\n}\n// ----\n// f() -> 2, 0x5c00000000000000000000000000000000000000000000000000000000000000, 0x5c00000000000000000000000000000000000000000000000000000000000000\n" + }, + "ternary_operator_with_literal_types_overflow.sol": { + "content": "contract TestTernary\n{\n function h() pure public returns (uint16 b)\n {\n b = (true ? 63 : 255) + (false ? 63 : 255);\n }\n\n function g() pure public returns (uint16 a)\n {\n bool t = true;\n bool f = false;\n a = (t ? 63 : 255) + (f ? 63 : 255);\n }\n}\n// ----\n// g() -> FAILURE, hex\"4e487b71\", 0x11\n// h() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "gwei.sol": { + "content": "contract C {\n\tuint constant x = 1 gwei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000000\n" + }, + "ether.sol": { + "content": "contract C {\n\tuint constant x = 1 ether;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_fractional_denominations/fractional_denominations.sol b/examples/test/semanticTests/literals_fractional_denominations/fractional_denominations.sol new file mode 100644 index 00000000..6bc448f0 --- /dev/null +++ b/examples/test/semanticTests/literals_fractional_denominations/fractional_denominations.sol @@ -0,0 +1,15 @@ +contract C { + uint public g = 1.5 gwei; + uint public e = 1.5 ether; + uint public m = 1.5 minutes; + uint public h = 1.5 hours; + uint public d = 1.5 days; + uint public w = 1.5 weeks; +} +// ---- +// g() -> 1500000000 +// e() -> 1500000000000000000 +// m() -> 90 +// h() -> 5400 +// d() -> 129600 +// w() -> 907200 diff --git a/examples/test/semanticTests/literals_fractional_denominations/fractional_denominations_standard_input.json b/examples/test/semanticTests/literals_fractional_denominations/fractional_denominations_standard_input.json new file mode 100644 index 00000000..59aaa238 --- /dev/null +++ b/examples/test/semanticTests/literals_fractional_denominations/fractional_denominations_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + }, + "scientific_notation.sol": { + "content": "contract C {\n function f() public returns(uint) {\n return 2e10 wei;\n }\n\n function g() public returns(uint) {\n return 200e-2 wei;\n }\n\n function h() public returns(uint) {\n return 2.5e1;\n }\n\n function i() public returns(int) {\n return -2e10;\n }\n\n function j() public returns(int) {\n return -200e-2;\n }\n\n function k() public returns(int) {\n return -2.5e1;\n }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n" + }, + "fractional_denominations.sol": { + "content": "contract C {\n uint public g = 1.5 gwei;\n uint public e = 1.5 ether;\n uint public m = 1.5 minutes;\n uint public h = 1.5 hours;\n uint public d = 1.5 days;\n uint public w = 1.5 weeks;\n}\n// ----\n// g() -> 1500000000\n// e() -> 1500000000000000000\n// m() -> 90\n// h() -> 5400\n// d() -> 129600\n// w() -> 907200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_gwei/gwei.sol b/examples/test/semanticTests/literals_gwei/gwei.sol new file mode 100644 index 00000000..bb8cc6ab --- /dev/null +++ b/examples/test/semanticTests/literals_gwei/gwei.sol @@ -0,0 +1,7 @@ +contract C { + uint constant x = 1 gwei; + + function f() public view returns(uint) { return x; } +} +// ---- +// f() -> 1000000000 diff --git a/examples/test/semanticTests/literals_gwei/gwei_standard_input.json b/examples/test/semanticTests/literals_gwei/gwei_standard_input.json new file mode 100644 index 00000000..5bdc5be7 --- /dev/null +++ b/examples/test/semanticTests/literals_gwei/gwei_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + }, + "scientific_notation.sol": { + "content": "contract C {\n function f() public returns(uint) {\n return 2e10 wei;\n }\n\n function g() public returns(uint) {\n return 200e-2 wei;\n }\n\n function h() public returns(uint) {\n return 2.5e1;\n }\n\n function i() public returns(int) {\n return -2e10;\n }\n\n function j() public returns(int) {\n return -200e-2;\n }\n\n function k() public returns(int) {\n return -2.5e1;\n }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n" + }, + "fractional_denominations.sol": { + "content": "contract C {\n uint public g = 1.5 gwei;\n uint public e = 1.5 ether;\n uint public m = 1.5 minutes;\n uint public h = 1.5 hours;\n uint public d = 1.5 days;\n uint public w = 1.5 weeks;\n}\n// ----\n// g() -> 1500000000\n// e() -> 1500000000000000000\n// m() -> 90\n// h() -> 5400\n// d() -> 129600\n// w() -> 907200\n" + }, + "escape.sol": { + "content": "pragma abicoder v2;\n\ncontract C\n{\n\tfunction f() public pure returns (uint, bytes1, bytes1) {\n\t\tbytes memory encoded = abi.encodePacked(\"\\\\\\\\\");\n\t\treturn (encoded.length, encoded[0], encoded[1]);\n\t}\n}\n// ----\n// f() -> 2, 0x5c00000000000000000000000000000000000000000000000000000000000000, 0x5c00000000000000000000000000000000000000000000000000000000000000\n" + }, + "ternary_operator_with_literal_types_overflow.sol": { + "content": "contract TestTernary\n{\n function h() pure public returns (uint16 b)\n {\n b = (true ? 63 : 255) + (false ? 63 : 255);\n }\n\n function g() pure public returns (uint16 a)\n {\n bool t = true;\n bool f = false;\n a = (t ? 63 : 255) + (f ? 63 : 255);\n }\n}\n// ----\n// g() -> FAILURE, hex\"4e487b71\", 0x11\n// h() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "gwei.sol": { + "content": "contract C {\n\tuint constant x = 1 gwei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters.sol b/examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters.sol new file mode 100644 index 00000000..3edd6049 --- /dev/null +++ b/examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (bytes32 result) { + assembly { + result := hex"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + } + } +} +// ---- +// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f diff --git a/examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters_standard_input.json b/examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters_standard_input.json new file mode 100644 index 00000000..fce5e997 --- /dev/null +++ b/examples/test/semanticTests/literals_hex_string_with_non_printable_characters/hex_string_with_non_printable_characters_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore.sol b/examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore.sol new file mode 100644 index 00000000..db7f70f8 --- /dev/null +++ b/examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure returns(bytes memory) { + return hex"12_34_5678_9A"; + } +} +// ---- +// f() -> 32, 5, left(0x123456789A) diff --git a/examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore_standard_input.json b/examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore_standard_input.json new file mode 100644 index 00000000..8692f77b --- /dev/null +++ b/examples/test/semanticTests/literals_hex_string_with_underscore/hex_string_with_underscore_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_scientific_notation/scientific_notation.sol b/examples/test/semanticTests/literals_scientific_notation/scientific_notation.sol new file mode 100644 index 00000000..5e0d8014 --- /dev/null +++ b/examples/test/semanticTests/literals_scientific_notation/scientific_notation.sol @@ -0,0 +1,32 @@ +contract C { + function f() public returns(uint) { + return 2e10 wei; + } + + function g() public returns(uint) { + return 200e-2 wei; + } + + function h() public returns(uint) { + return 2.5e1; + } + + function i() public returns(int) { + return -2e10; + } + + function j() public returns(int) { + return -200e-2; + } + + function k() public returns(int) { + return -2.5e1; + } +} +// ---- +// f() -> 20000000000 +// g() -> 2 +// h() -> 25 +// i() -> -20000000000 +// j() -> -2 +// k() -> -25 diff --git a/examples/test/semanticTests/literals_scientific_notation/scientific_notation_standard_input.json b/examples/test/semanticTests/literals_scientific_notation/scientific_notation_standard_input.json new file mode 100644 index 00000000..cb6c51b6 --- /dev/null +++ b/examples/test/semanticTests/literals_scientific_notation/scientific_notation_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + }, + "scientific_notation.sol": { + "content": "contract C {\n function f() public returns(uint) {\n return 2e10 wei;\n }\n\n function g() public returns(uint) {\n return 200e-2 wei;\n }\n\n function h() public returns(uint) {\n return 2.5e1;\n }\n\n function i() public returns(int) {\n return -2e10;\n }\n\n function j() public returns(int) {\n return -200e-2;\n }\n\n function k() public returns(int) {\n return -2.5e1;\n }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow.sol b/examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow.sol new file mode 100644 index 00000000..82ec72d8 --- /dev/null +++ b/examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow.sol @@ -0,0 +1,17 @@ +contract TestTernary +{ + function h() pure public returns (uint16 b) + { + b = (true ? 63 : 255) + (false ? 63 : 255); + } + + function g() pure public returns (uint16 a) + { + bool t = true; + bool f = false; + a = (t ? 63 : 255) + (f ? 63 : 255); + } +} +// ---- +// g() -> FAILURE, hex"4e487b71", 0x11 +// h() -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow_standard_input.json b/examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow_standard_input.json new file mode 100644 index 00000000..cc4cf260 --- /dev/null +++ b/examples/test/semanticTests/literals_ternary_operator_with_literal_types_overflow/ternary_operator_with_literal_types_overflow_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + }, + "denominations_in_array_sizes.sol": { + "content": "contract C {\n uint[2 wei] a;\n uint[2 gwei] b;\n uint[2 ether] c;\n uint[2 seconds] d;\n uint[2 minutes] e;\n uint[2 hours] f;\n uint[2 days] g;\n uint[2 weeks] h;\n\n function lengths() public returns (uint, uint, uint, uint, uint, uint, uint, uint) {\n return (\n a.length,\n b.length,\n c.length,\n d.length,\n e.length,\n f.length,\n g.length,\n h.length\n );\n }\n}\n// ----\n// lengths() -> 2, 2000000000, 2000000000000000000, 2, 120, 7200, 172800, 1209600\n" + }, + "hex_string_with_non_printable_characters.sol": { + "content": "contract C {\n function f() public pure returns (bytes32 result) {\n assembly {\n result := hex\"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"\n }\n }\n}\n// ----\n// f() -> 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n" + }, + "denominations.sol": { + "content": "contract C {\n\tuint constant x = 1 ether + 1 gwei + 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1000000001000000001\n" + }, + "hex_string_with_underscore.sol": { + "content": "contract C {\n function f() public pure returns(bytes memory) {\n return hex\"12_34_5678_9A\";\n }\n}\n// ----\n// f() -> 32, 5, left(0x123456789A)\n" + }, + "scientific_notation.sol": { + "content": "contract C {\n function f() public returns(uint) {\n return 2e10 wei;\n }\n\n function g() public returns(uint) {\n return 200e-2 wei;\n }\n\n function h() public returns(uint) {\n return 2.5e1;\n }\n\n function i() public returns(int) {\n return -2e10;\n }\n\n function j() public returns(int) {\n return -200e-2;\n }\n\n function k() public returns(int) {\n return -2.5e1;\n }\n}\n// ----\n// f() -> 20000000000\n// g() -> 2\n// h() -> 25\n// i() -> -20000000000\n// j() -> -2\n// k() -> -25\n" + }, + "fractional_denominations.sol": { + "content": "contract C {\n uint public g = 1.5 gwei;\n uint public e = 1.5 ether;\n uint public m = 1.5 minutes;\n uint public h = 1.5 hours;\n uint public d = 1.5 days;\n uint public w = 1.5 weeks;\n}\n// ----\n// g() -> 1500000000\n// e() -> 1500000000000000000\n// m() -> 90\n// h() -> 5400\n// d() -> 129600\n// w() -> 907200\n" + }, + "escape.sol": { + "content": "pragma abicoder v2;\n\ncontract C\n{\n\tfunction f() public pure returns (uint, bytes1, bytes1) {\n\t\tbytes memory encoded = abi.encodePacked(\"\\\\\\\\\");\n\t\treturn (encoded.length, encoded[0], encoded[1]);\n\t}\n}\n// ----\n// f() -> 2, 0x5c00000000000000000000000000000000000000000000000000000000000000, 0x5c00000000000000000000000000000000000000000000000000000000000000\n" + }, + "ternary_operator_with_literal_types_overflow.sol": { + "content": "contract TestTernary\n{\n function h() pure public returns (uint16 b)\n {\n b = (true ? 63 : 255) + (false ? 63 : 255);\n }\n\n function g() pure public returns (uint16 a)\n {\n bool t = true;\n bool f = false;\n a = (t ? 63 : 255) + (f ? 63 : 255);\n }\n}\n// ----\n// g() -> FAILURE, hex\"4e487b71\", 0x11\n// h() -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/literals_wei/wei.sol b/examples/test/semanticTests/literals_wei/wei.sol new file mode 100644 index 00000000..08bba771 --- /dev/null +++ b/examples/test/semanticTests/literals_wei/wei.sol @@ -0,0 +1,7 @@ +contract C { + uint constant x = 1 wei; + + function f() public view returns(uint) { return x; } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/literals_wei/wei_standard_input.json b/examples/test/semanticTests/literals_wei/wei_standard_input.json new file mode 100644 index 00000000..1e98c6b7 --- /dev/null +++ b/examples/test/semanticTests/literals_wei/wei_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "wei.sol": { + "content": "contract C {\n\tuint constant x = 1 wei;\n\n\tfunction f() public view returns(uint) { return x; }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/memoryManagement_assembly_access/assembly_access.sol b/examples/test/semanticTests/memoryManagement_assembly_access/assembly_access.sol new file mode 100644 index 00000000..d2ed3575 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_assembly_access/assembly_access.sol @@ -0,0 +1,14 @@ +contract C { + function f() public pure { + uint[] memory x; + uint y; + assembly { + y := x + } + // The value of an uninitialized dynamic array is not zero but rather + // an address of a location in memory that has the value of zero. + assert(y != 0); + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/memoryManagement_assembly_access/assembly_access_standard_input.json b/examples/test/semanticTests/memoryManagement_assembly_access/assembly_access_standard_input.json new file mode 100644 index 00000000..7cce78c0 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_assembly_access/assembly_access_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "struct_allocation.sol": { + "content": "contract C {\n struct S { uint x; uint y; uint z; }\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n S memory x = S(1, 2, 3);\n uint memorySizeBefore = memorySize();\n S memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint memorySizeBefore = memorySize();\n S memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x60\n" + }, + "assembly_access.sol": { + "content": "contract C {\n function f() public pure {\n uint[] memory x;\n uint y;\n assembly {\n y := x\n }\n // The value of an uninitialized dynamic array is not zero but rather\n // an address of a location in memory that has the value of zero.\n assert(y != 0);\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation.sol b/examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation.sol new file mode 100644 index 00000000..ed51a599 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation.sol @@ -0,0 +1,15 @@ +contract Test { + mapping(uint=>uint) data; + function stat() public returns (uint[5] memory) + { + data[2] = 3; // make sure to use some memory + } + function dyn() public returns (uint[] memory) { stat(); } + function nested() public returns (uint[3][] memory) { stat(); } + function nestedStat() public returns (uint[3][7] memory) { stat(); } +} +// ---- +// stat() -> 0, 0, 0, 0, 0 +// dyn() -> 0x20, 0 +// nested() -> 0x20, 0 +// nestedStat() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 diff --git a/examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation_standard_input.json b/examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation_standard_input.json new file mode 100644 index 00000000..e5f3b9c1 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_memory_types_initialisation/memory_types_initialisation_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "struct_allocation.sol": { + "content": "contract C {\n struct S { uint x; uint y; uint z; }\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n S memory x = S(1, 2, 3);\n uint memorySizeBefore = memorySize();\n S memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint memorySizeBefore = memorySize();\n S memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x60\n" + }, + "assembly_access.sol": { + "content": "contract C {\n function f() public pure {\n uint[] memory x;\n uint y;\n assembly {\n y := x\n }\n // The value of an uninitialized dynamic array is not zero but rather\n // an address of a location in memory that has the value of zero.\n assert(y != 0);\n }\n}\n// ----\n// f() ->\n" + }, + "static_memory_array_allocation.sol": { + "content": "contract C {\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n uint[20] memory x;\n uint memorySizeBefore = memorySize();\n uint[20] memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint[20] memory x;\n uint memorySizeBefore = memorySize();\n uint[20] memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x0280\n" + }, + "return_variable.sol": { + "content": "contract C {\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function f() public returns (uint, uint, uint) {\n uint a = memorySize();\n g();\n uint b = memorySize();\n h();\n uint c = memorySize();\n i();\n uint d = memorySize();\n return (b - a, c - b, d - c);\n }\n // In these functions, we do allocate memory in both cases.\n // In `i()`, this could be avoided but we would have to check\n // that all code paths return explicitly and provide a value.\n function g() internal returns (uint[40] memory) {\n }\n function h() internal returns (uint[40] memory t) {\n }\n function i() internal returns (uint[40] memory) {\n uint[40] memory x;\n return x;\n }\n}\n// ----\n// f() -> 0x0500, 0x0500, 0x0a00\n" + }, + "memory_types_initialisation.sol": { + "content": "contract Test {\n mapping(uint=>uint) data;\n function stat() public returns (uint[5] memory)\n {\n data[2] = 3; // make sure to use some memory\n }\n function dyn() public returns (uint[] memory) { stat(); }\n function nested() public returns (uint[3][] memory) { stat(); }\n function nestedStat() public returns (uint[3][7] memory) { stat(); }\n}\n// ----\n// stat() -> 0, 0, 0, 0, 0\n// dyn() -> 0x20, 0\n// nested() -> 0x20, 0\n// nestedStat() -> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/memoryManagement_return_variable/return_variable.sol b/examples/test/semanticTests/memoryManagement_return_variable/return_variable.sol new file mode 100644 index 00000000..a28672c9 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_return_variable/return_variable.sol @@ -0,0 +1,28 @@ +contract C { + function memorySize() internal pure returns (uint s) { + assembly { s := mload(0x40) } + } + function f() public returns (uint, uint, uint) { + uint a = memorySize(); + g(); + uint b = memorySize(); + h(); + uint c = memorySize(); + i(); + uint d = memorySize(); + return (b - a, c - b, d - c); + } + // In these functions, we do allocate memory in both cases. + // In `i()`, this could be avoided but we would have to check + // that all code paths return explicitly and provide a value. + function g() internal returns (uint[40] memory) { + } + function h() internal returns (uint[40] memory t) { + } + function i() internal returns (uint[40] memory) { + uint[40] memory x; + return x; + } +} +// ---- +// f() -> 0x0500, 0x0500, 0x0a00 diff --git a/examples/test/semanticTests/memoryManagement_return_variable/return_variable_standard_input.json b/examples/test/semanticTests/memoryManagement_return_variable/return_variable_standard_input.json new file mode 100644 index 00000000..900ff3a0 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_return_variable/return_variable_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "struct_allocation.sol": { + "content": "contract C {\n struct S { uint x; uint y; uint z; }\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n S memory x = S(1, 2, 3);\n uint memorySizeBefore = memorySize();\n S memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint memorySizeBefore = memorySize();\n S memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x60\n" + }, + "assembly_access.sol": { + "content": "contract C {\n function f() public pure {\n uint[] memory x;\n uint y;\n assembly {\n y := x\n }\n // The value of an uninitialized dynamic array is not zero but rather\n // an address of a location in memory that has the value of zero.\n assert(y != 0);\n }\n}\n// ----\n// f() ->\n" + }, + "static_memory_array_allocation.sol": { + "content": "contract C {\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n uint[20] memory x;\n uint memorySizeBefore = memorySize();\n uint[20] memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint[20] memory x;\n uint memorySizeBefore = memorySize();\n uint[20] memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x0280\n" + }, + "return_variable.sol": { + "content": "contract C {\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function f() public returns (uint, uint, uint) {\n uint a = memorySize();\n g();\n uint b = memorySize();\n h();\n uint c = memorySize();\n i();\n uint d = memorySize();\n return (b - a, c - b, d - c);\n }\n // In these functions, we do allocate memory in both cases.\n // In `i()`, this could be avoided but we would have to check\n // that all code paths return explicitly and provide a value.\n function g() internal returns (uint[40] memory) {\n }\n function h() internal returns (uint[40] memory t) {\n }\n function i() internal returns (uint[40] memory) {\n uint[40] memory x;\n return x;\n }\n}\n// ----\n// f() -> 0x0500, 0x0500, 0x0a00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation.sol b/examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation.sol new file mode 100644 index 00000000..9b27b349 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation.sol @@ -0,0 +1,22 @@ +contract C { + function memorySize() internal pure returns (uint s) { + assembly { s := mload(0x40) } + } + function withValue() public pure returns (uint) { + uint[20] memory x; + uint memorySizeBefore = memorySize(); + uint[20] memory t = x; + uint memorySizeAfter = memorySize(); + return memorySizeAfter - memorySizeBefore; + } + function withoutValue() public pure returns (uint) { + uint[20] memory x; + uint memorySizeBefore = memorySize(); + uint[20] memory t; + uint memorySizeAfter = memorySize(); + return memorySizeAfter - memorySizeBefore; + } +} +// ---- +// withValue() -> 0x00 +// withoutValue() -> 0x0280 diff --git a/examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation_standard_input.json b/examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation_standard_input.json new file mode 100644 index 00000000..47569160 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_static_memory_array_allocation/static_memory_array_allocation_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "struct_allocation.sol": { + "content": "contract C {\n struct S { uint x; uint y; uint z; }\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n S memory x = S(1, 2, 3);\n uint memorySizeBefore = memorySize();\n S memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint memorySizeBefore = memorySize();\n S memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x60\n" + }, + "assembly_access.sol": { + "content": "contract C {\n function f() public pure {\n uint[] memory x;\n uint y;\n assembly {\n y := x\n }\n // The value of an uninitialized dynamic array is not zero but rather\n // an address of a location in memory that has the value of zero.\n assert(y != 0);\n }\n}\n// ----\n// f() ->\n" + }, + "static_memory_array_allocation.sol": { + "content": "contract C {\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n uint[20] memory x;\n uint memorySizeBefore = memorySize();\n uint[20] memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint[20] memory x;\n uint memorySizeBefore = memorySize();\n uint[20] memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x0280\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation.sol b/examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation.sol new file mode 100644 index 00000000..5b471e1a --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation.sol @@ -0,0 +1,22 @@ +contract C { + struct S { uint x; uint y; uint z; } + function memorySize() internal pure returns (uint s) { + assembly { s := mload(0x40) } + } + function withValue() public pure returns (uint) { + S memory x = S(1, 2, 3); + uint memorySizeBefore = memorySize(); + S memory t = x; + uint memorySizeAfter = memorySize(); + return memorySizeAfter - memorySizeBefore; + } + function withoutValue() public pure returns (uint) { + uint memorySizeBefore = memorySize(); + S memory t; + uint memorySizeAfter = memorySize(); + return memorySizeAfter - memorySizeBefore; + } +} +// ---- +// withValue() -> 0x00 +// withoutValue() -> 0x60 diff --git a/examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation_standard_input.json b/examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation_standard_input.json new file mode 100644 index 00000000..3b821072 --- /dev/null +++ b/examples/test/semanticTests/memoryManagement_struct_allocation/struct_allocation_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "struct_allocation.sol": { + "content": "contract C {\n struct S { uint x; uint y; uint z; }\n function memorySize() internal pure returns (uint s) {\n assembly { s := mload(0x40) }\n }\n function withValue() public pure returns (uint) {\n S memory x = S(1, 2, 3);\n uint memorySizeBefore = memorySize();\n S memory t = x;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n function withoutValue() public pure returns (uint) {\n uint memorySizeBefore = memorySize();\n S memory t;\n uint memorySizeAfter = memorySize();\n return memorySizeAfter - memorySizeBefore;\n }\n}\n// ----\n// withValue() -> 0x00\n// withoutValue() -> 0x60\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract.sol b/examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract.sol new file mode 100644 index 00000000..efdaedf5 --- /dev/null +++ b/examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract.sol @@ -0,0 +1,28 @@ +abstract contract A { + function f() virtual public pure; +} + +interface I { + function f() external pure; +} + +contract C { + function f() pure public { + } +} + +contract Test is C { + function c() public pure returns (string memory) { + return type(C).name; + } + function a() public pure returns (string memory) { + return type(A).name; + } + function i() public pure returns (string memory) { + return type(I).name; + } +} +// ---- +// c() -> 0x20, 1, "C" +// a() -> 0x20, 1, "A" +// i() -> 0x20, 1, "I" diff --git a/examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract_standard_input.json b/examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract_standard_input.json new file mode 100644 index 00000000..15d7d03f --- /dev/null +++ b/examples/test/semanticTests/metaTypes_name_other_contract/name_other_contract_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "name_other_contract.sol": { + "content": "abstract contract A {\n function f() virtual public pure;\n}\n\ninterface I {\n function f() external pure;\n}\n\ncontract C {\n function f() pure public {\n }\n}\n\ncontract Test is C {\n function c() public pure returns (string memory) {\n return type(C).name;\n }\n function a() public pure returns (string memory) {\n return type(A).name;\n }\n function i() public pure returns (string memory) {\n return type(I).name;\n }\n}\n// ----\n// c() -> 0x20, 1, \"C\"\n// a() -> 0x20, 1, \"A\"\n// i() -> 0x20, 1, \"I\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name.sol b/examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name.sol new file mode 100644 index 00000000..4d1538d7 --- /dev/null +++ b/examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name.sol @@ -0,0 +1,22 @@ +contract A { + uint public x = 7; + modifier m virtual { x = 2; _; } +} +contract C is A { + modifier m override { x = 1; _; } + + function f() public A.m returns (uint) { + return 9; + } + function g() public m returns (uint) { + return 10; + } +} +// ---- +// x() -> 7 +// f() -> 9 +// x() -> 2 +// g() -> 0x0a +// x() -> 1 +// f() -> 9 +// x() -> 2 diff --git a/examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name_standard_input.json b/examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name_standard_input.json new file mode 100644 index 00000000..64fdda3e --- /dev/null +++ b/examples/test/semanticTests/modifiers_access_through_contract_name/access_through_contract_name_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name.sol b/examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name.sol new file mode 100644 index 00000000..58c60014 --- /dev/null +++ b/examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name.sol @@ -0,0 +1,25 @@ +==== Source: a ==== +import "a" as M; +contract C { + uint public x; + modifier m { x = 1; _; } + + function f() public M.M.C.m returns (uint t, uint r) { + t = x; + x = 3; + r = 9; + } + function g() public m returns (uint t, uint r) { + t = x; + x = 4; + r = 10; + } +} +// ---- +// x() -> 0x00 +// f() -> 1, 9 +// x() -> 3 +// g() -> 1, 0x0a +// x() -> 4 +// f() -> 1, 9 +// x() -> 3 diff --git a/examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name_standard_input.json b/examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name_standard_input.json new file mode 100644 index 00000000..978d4222 --- /dev/null +++ b/examples/test/semanticTests/modifiers_access_through_module_name/access_through_module_name_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier.sol b/examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier.sol new file mode 100644 index 00000000..67fc0e6b --- /dev/null +++ b/examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier.sol @@ -0,0 +1,20 @@ +contract C { + uint256 public x; + modifier run() { + for (uint256 i = 0; i < 10; i++) { + _; + if (i == 1) + break; + } + } + + function f() public run { + uint256 k = x; + uint256 t = k + 1; + x = t; + } +} +// ---- +// x() -> 0 +// f() -> +// x() -> 2 diff --git a/examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier_standard_input.json b/examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier_standard_input.json new file mode 100644 index 00000000..36f67463 --- /dev/null +++ b/examples/test/semanticTests/modifiers_break_in_modifier/break_in_modifier_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier.sol b/examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier.sol new file mode 100644 index 00000000..2879c55e --- /dev/null +++ b/examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier.sol @@ -0,0 +1,19 @@ +contract C { + uint256 public x; + modifier run() { + for (uint256 i = 0; i < 10; i++) { + if (i % 2 == 1) continue; + _; + } + } + + function f() public run { + uint256 k = x; + uint256 t = k + 1; + x = t; + } +} +// ---- +// x() -> 0 +// f() -> +// x() -> 5 diff --git a/examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier_standard_input.json b/examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier_standard_input.json new file mode 100644 index 00000000..0b822edd --- /dev/null +++ b/examples/test/semanticTests/modifiers_continue_in_modifier/continue_in_modifier_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_evaluation_order/evaluation_order.sol b/examples/test/semanticTests/modifiers_evaluation_order/evaluation_order.sol new file mode 100644 index 00000000..b92df61f --- /dev/null +++ b/examples/test/semanticTests/modifiers_evaluation_order/evaluation_order.sol @@ -0,0 +1,20 @@ +contract A { constructor(uint) {} } +contract B { constructor(uint) {} } +contract C { constructor(uint) {} } + +contract D is A, B, C { + uint[] x; + constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) { + f(7); + } + + function query() public view returns (uint[] memory) { return x; } + + modifier m1(uint) { _; } + modifier m2(uint) { _; } + modifier m3(uint) { _; } + + function f(uint y) internal returns (uint) { x.push(y); return 0; } +} +// ---- +// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7 diff --git a/examples/test/semanticTests/modifiers_evaluation_order/evaluation_order_standard_input.json b/examples/test/semanticTests/modifiers_evaluation_order/evaluation_order_standard_input.json new file mode 100644 index 00000000..4c44287f --- /dev/null +++ b/examples/test/semanticTests/modifiers_evaluation_order/evaluation_order_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier/function_modifier.sol b/examples/test/semanticTests/modifiers_function_modifier/function_modifier.sol new file mode 100644 index 00000000..e1978ba8 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier/function_modifier.sol @@ -0,0 +1,12 @@ +contract C { + function getOne() public payable nonFree returns (uint256 r) { + return 1; + } + + modifier nonFree { + if (msg.value > 0) _; + } +} +// ---- +// getOne() -> 0 +// getOne(), 1 wei -> 1 diff --git a/examples/test/semanticTests/modifiers_function_modifier/function_modifier_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier/function_modifier_standard_input.json new file mode 100644 index 00000000..a00d9f94 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier/function_modifier_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context.sol b/examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context.sol new file mode 100644 index 00000000..bae50325 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context.sol @@ -0,0 +1,48 @@ +contract A { + uint256 data; + + constructor() mod1 { + f1(); + } + + function f1() public mod2 { + data |= 0x1; + } + + function f2() public { + data |= 0x20; + } + + function f3() public virtual {} + + modifier mod1 virtual { + f2(); + _; + } + modifier mod2 { + f3(); + if (false) _; + } + + function getData() public returns (uint256 r) { + return data; + } +} + + +contract C is A { + modifier mod1 override { + f4(); + _; + } + + function f3() public override { + data |= 0x300; + } + + function f4() public { + data |= 0x4000; + } +} +// ---- +// getData() -> 0x4300 diff --git a/examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context_standard_input.json new file mode 100644 index 00000000..fd83d2f6 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_calling_functions_in_creation_context/function_modifier_calling_functions_in_creation_context_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty.sol b/examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty.sol new file mode 100644 index 00000000..16cbad1a --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty.sol @@ -0,0 +1,16 @@ +abstract contract A { + function f() public mod returns (bool r) { + return true; + } + + modifier mod virtual; +} + + +contract C is A { + modifier mod override { + if (false) _; + } +} +// ---- +// f() -> false diff --git a/examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty_standard_input.json new file mode 100644 index 00000000..2a96d368 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_empty/function_modifier_empty_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor.sol b/examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor.sol new file mode 100644 index 00000000..f32a2381 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor.sol @@ -0,0 +1,26 @@ +contract A { + uint256 data; + + constructor() mod1 { + data |= 2; + } + + modifier mod1 virtual { + data |= 1; + _; + } + + function getData() public returns (uint256 r) { + return data; + } +} + + +contract C is A { + modifier mod1 override { + data |= 4; + _; + } +} +// ---- +// getData() -> 6 diff --git a/examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor_standard_input.json new file mode 100644 index 00000000..001eb287 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_for_constructor/function_modifier_for_constructor_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library.sol b/examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library.sol new file mode 100644 index 00000000..c50fb5dd --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library.sol @@ -0,0 +1,27 @@ +library L { + struct S { + uint256 v; + } + modifier mod(S storage s) { + s.v++; + _; + } + + function libFun(S storage s) internal mod(s) { + s.v += 0x100; + } +} + + +contract Test { + using L for *; + L.S s; + + function f() public returns (uint256) { + s.libFun(); + L.libFun(s); + return s.v; + } +} +// ---- +// f() -> 0x202 diff --git a/examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library_standard_input.json new file mode 100644 index 00000000..e32aa3c1 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_library/function_modifier_library_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + }, + "modifier_in_constructor_ice.sol": { + "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n" + }, + "function_return_parameter_complex.sol": { + "content": "// Test to see if the function return parameter, when forwarded to the modifier actually has value\n// zero.\ncontract A {\n uint public x = 0;\n\n modifier alwaysZeros(uint256 a, uint256 b) {\n x++;\n _;\n require(a == 0, \"a is not zero\");\n require(b == 0, \"b is not zero\");\n }\n\n function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) {\n r1 = 16;\n r2 = 32;\n r3 = 64;\n }\n\n function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) {\n r = 0;\n }\n\n // The value of x would be 1 before calling this. It gets incremented four times in total during\n // the modifier calls\n function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) {\n r = x;\n }\n}\n// ----\n// f() -> 0x10, 0x20, 0x40\n// x() -> 1\n// shouldFail(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"a is not zero\"\n// shouldFail(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"b is not zero\"\n// x() -> 1\n// g() -> 5\n// x() -> 5\n" + }, + "function_modifier_multiple_times_local_vars.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n uint256 b = x;\n a += b;\n _;\n a -= b;\n assert(b == x);\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 0\n" + }, + "function_modifier_library.sol": { + "content": "library L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance.sol b/examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance.sol new file mode 100644 index 00000000..e87ac7a4 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance.sol @@ -0,0 +1,33 @@ +// Tests that virtual lookup for modifiers in libraries does not consider +// the current inheritance hierarchy. +library L { + struct S { + uint256 v; + } + modifier mod(S storage s) { + s.v++; + _; + } + + function libFun(S storage s) internal mod(s) { + s.v += 0x100; + } +} + + +contract Test { + using L for *; + L.S s; + modifier mod(L.S storage) { + revert(); + _; + } + + function f() public returns (uint256) { + s.libFun(); + L.libFun(s); + return s.v; + } +} +// ---- +// f() -> 0x202 diff --git a/examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance_standard_input.json new file mode 100644 index 00000000..aed224a2 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_library_inheritance/function_modifier_library_inheritance_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables.sol b/examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables.sol new file mode 100644 index 00000000..c3b10475 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables.sol @@ -0,0 +1,18 @@ +contract C { + modifier mod1 { + uint8 a = 1; + uint8 b = 2; + _; + } + modifier mod2(bool a) { + if (a) return; + else _; + } + + function f(bool a) public mod1 mod2(a) returns (uint256 r) { + return 3; + } +} +// ---- +// f(bool): true -> 0 +// f(bool): false -> 3 diff --git a/examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables_standard_input.json new file mode 100644 index 00000000..d6982454 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_local_variables/function_modifier_local_variables_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop.sol b/examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop.sol new file mode 100644 index 00000000..2b290022 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop.sol @@ -0,0 +1,19 @@ +contract C { + modifier repeat(uint256 count) { + uint256 i; + for (i = 0; i < count; ++i) _; + } + + function f() public repeat(10) returns (uint256 r) { + r += 1; + } +} +// via yul disabled because the return variables are +// fresh variables each time, while in the old code generator, +// they share a stack slot when the function is +// invoked multiple times via `_`. + +// ==== +// compileViaYul: false +// ---- +// f() -> 10 diff --git a/examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop_standard_input.json new file mode 100644 index 00000000..1ad48d66 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_loop/function_modifier_loop_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair.sol b/examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair.sol new file mode 100644 index 00000000..81caba76 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair.sol @@ -0,0 +1,14 @@ +contract C { + modifier repeat(uint256 count) { + uint256 i; + for (i = 0; i < count; ++i) _; + } + + function f() public repeat(10) returns (uint256 r) { + r += 1; + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair_standard_input.json new file mode 100644 index 00000000..546923d0 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_loop_viair/function_modifier_loop_viair_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation.sol b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation.sol new file mode 100644 index 00000000..f4e04480 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation.sol @@ -0,0 +1,20 @@ +contract C { + modifier repeat(bool twice) { + if (twice) _; + _; + } + + function f(bool twice) public repeat(twice) returns (uint256 r) { + r += 1; + } +} +// via yul disabled because the return variables are +// fresh variables each time, while in the old code generator, +// they share a stack slot when the function is +// invoked multiple times via `_`. + +// ==== +// compileViaYul: false +// ---- +// f(bool): false -> 1 +// f(bool): true -> 2 diff --git a/examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation_standard_input.json new file mode 100644 index 00000000..d0892b9c --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation/function_modifier_multi_invocation_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair.sol b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair.sol new file mode 100644 index 00000000..929b006e --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair.sol @@ -0,0 +1,15 @@ +contract C { + modifier repeat(bool twice) { + if (twice) _; + _; + } + + function f(bool twice) public repeat(twice) returns (uint256 r) { + r += 1; + } +} +// ==== +// compileViaYul: true +// ---- +// f(bool): false -> 1 +// f(bool): true -> 1 diff --git a/examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair_standard_input.json new file mode 100644 index 00000000..76ae72cb --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multi_invocation_viair/function_modifier_multi_invocation_viair_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + }, + "modifier_in_constructor_ice.sol": { + "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n" + }, + "function_return_parameter_complex.sol": { + "content": "// Test to see if the function return parameter, when forwarded to the modifier actually has value\n// zero.\ncontract A {\n uint public x = 0;\n\n modifier alwaysZeros(uint256 a, uint256 b) {\n x++;\n _;\n require(a == 0, \"a is not zero\");\n require(b == 0, \"b is not zero\");\n }\n\n function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) {\n r1 = 16;\n r2 = 32;\n r3 = 64;\n }\n\n function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) {\n r = 0;\n }\n\n // The value of x would be 1 before calling this. It gets incremented four times in total during\n // the modifier calls\n function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) {\n r = x;\n }\n}\n// ----\n// f() -> 0x10, 0x20, 0x40\n// x() -> 1\n// shouldFail(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"a is not zero\"\n// shouldFail(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"b is not zero\"\n// x() -> 1\n// g() -> 5\n// x() -> 5\n" + }, + "function_modifier_multiple_times_local_vars.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n uint256 b = x;\n a += b;\n _;\n a -= b;\n assert(b == x);\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 0\n" + }, + "function_modifier_library.sol": { + "content": "library L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "function_modifier_multi_invocation_viair.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return.sol b/examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return.sol new file mode 100644 index 00000000..6058e351 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return.sol @@ -0,0 +1,23 @@ +// Note that return sets the return variable and jumps to the end of the current function or +// modifier code block. +contract C { + modifier repeat(bool twice) { + if (twice) _; + _; + } + + function f(bool twice) public repeat(twice) returns (uint256 r) { + r += 1; + return r; + } +} +// via yul disabled because the return variables are +// fresh variables each time, while in the old code generator, +// they share a stack slot when the function is +// invoked multiple times via `_`. + +// ==== +// compileViaYul: false +// ---- +// f(bool): false -> 1 +// f(bool): true -> 2 diff --git a/examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return_standard_input.json new file mode 100644 index 00000000..e5da8b95 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multi_with_return/function_modifier_multi_with_return_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times.sol b/examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times.sol new file mode 100644 index 00000000..5cda8b6d --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times.sol @@ -0,0 +1,14 @@ +contract C { + uint256 public a; + modifier mod(uint256 x) { + a += x; + _; + } + + function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) { + return a; + } +} +// ---- +// f(uint256): 3 -> 10 +// a() -> 10 diff --git a/examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times_standard_input.json new file mode 100644 index 00000000..b7f31cfe --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multiple_times/function_modifier_multiple_times_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars.sol b/examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars.sol new file mode 100644 index 00000000..780b5a36 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars.sol @@ -0,0 +1,17 @@ +contract C { + uint256 public a; + modifier mod(uint256 x) { + uint256 b = x; + a += b; + _; + a -= b; + assert(b == x); + } + + function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) { + return a; + } +} +// ---- +// f(uint256): 3 -> 10 +// a() -> 0 diff --git a/examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars_standard_input.json new file mode 100644 index 00000000..e8f880b9 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_multiple_times_local_vars/function_modifier_multiple_times_local_vars_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + }, + "modifier_in_constructor_ice.sol": { + "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n" + }, + "function_return_parameter_complex.sol": { + "content": "// Test to see if the function return parameter, when forwarded to the modifier actually has value\n// zero.\ncontract A {\n uint public x = 0;\n\n modifier alwaysZeros(uint256 a, uint256 b) {\n x++;\n _;\n require(a == 0, \"a is not zero\");\n require(b == 0, \"b is not zero\");\n }\n\n function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) {\n r1 = 16;\n r2 = 32;\n r3 = 64;\n }\n\n function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) {\n r = 0;\n }\n\n // The value of x would be 1 before calling this. It gets incremented four times in total during\n // the modifier calls\n function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) {\n r = x;\n }\n}\n// ----\n// f() -> 0x10, 0x20, 0x40\n// x() -> 1\n// shouldFail(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"a is not zero\"\n// shouldFail(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"b is not zero\"\n// x() -> 1\n// g() -> 5\n// x() -> 5\n" + }, + "function_modifier_multiple_times_local_vars.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n uint256 b = x;\n a += b;\n _;\n a -= b;\n assert(b == x);\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding.sol b/examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding.sol new file mode 100644 index 00000000..16d6b821 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding.sol @@ -0,0 +1,18 @@ +contract A { + function f() public mod returns (bool r) { + return true; + } + + modifier mod virtual { + _; + } +} + + +contract C is A { + modifier mod override { + if (false) _; + } +} +// ---- +// f() -> false diff --git a/examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding_standard_input.json new file mode 100644 index 00000000..581e1bf9 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_overriding/function_modifier_overriding_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference.sol b/examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference.sol new file mode 100644 index 00000000..f14496fa --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference.sol @@ -0,0 +1,13 @@ +contract C { + modifier m1(uint value) { + _; + } + modifier m2(uint value) { + _; + } + + function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) { + } +} +// ---- +// f() -> 2, 3 diff --git a/examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference_standard_input.json b/examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference_standard_input.json new file mode 100644 index 00000000..179b1fa4 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_modifier_return_reference/function_modifier_return_reference_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter.sol b/examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter.sol new file mode 100644 index 00000000..ecc7851b --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter.sol @@ -0,0 +1,8 @@ +// The IR of this contract used to throw +contract B { + function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { } + modifier mod1(uint a, bool b) { if (b) _; } + modifier mod2(bytes7 a) { while (a == "1234567") _; } +} +// ---- +// f(uint8): 5 -> 0x00 diff --git a/examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter_standard_input.json b/examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter_standard_input.json new file mode 100644 index 00000000..614a972f --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_return_parameter/function_return_parameter_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex.sol b/examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex.sol new file mode 100644 index 00000000..530fadf6 --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex.sol @@ -0,0 +1,36 @@ +// Test to see if the function return parameter, when forwarded to the modifier actually has value +// zero. +contract A { + uint public x = 0; + + modifier alwaysZeros(uint256 a, uint256 b) { + x++; + _; + require(a == 0, "a is not zero"); + require(b == 0, "b is not zero"); + } + + function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) { + r1 = 16; + r2 = 32; + r3 = 64; + } + + function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) { + r = 0; + } + + // The value of x would be 1 before calling this. It gets incremented four times in total during + // the modifier calls + function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) { + r = x; + } +} +// ---- +// f() -> 0x10, 0x20, 0x40 +// x() -> 1 +// shouldFail(uint256): 1 -> FAILURE, hex"08c379a0", 0x20, 13, "a is not zero" +// shouldFail(uint256): 0 -> FAILURE, hex"08c379a0", 0x20, 13, "b is not zero" +// x() -> 1 +// g() -> 5 +// x() -> 5 diff --git a/examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex_standard_input.json b/examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex_standard_input.json new file mode 100644 index 00000000..203f9b9d --- /dev/null +++ b/examples/test/semanticTests/modifiers_function_return_parameter_complex/function_return_parameter_complex_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + }, + "modifier_in_constructor_ice.sol": { + "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n" + }, + "function_return_parameter_complex.sol": { + "content": "// Test to see if the function return parameter, when forwarded to the modifier actually has value\n// zero.\ncontract A {\n uint public x = 0;\n\n modifier alwaysZeros(uint256 a, uint256 b) {\n x++;\n _;\n require(a == 0, \"a is not zero\");\n require(b == 0, \"b is not zero\");\n }\n\n function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) {\n r1 = 16;\n r2 = 32;\n r3 = 64;\n }\n\n function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) {\n r = 0;\n }\n\n // The value of x would be 1 before calling this. It gets incremented four times in total during\n // the modifier calls\n function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) {\n r = x;\n }\n}\n// ----\n// f() -> 0x10, 0x20, 0x40\n// x() -> 1\n// shouldFail(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"a is not zero\"\n// shouldFail(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"b is not zero\"\n// x() -> 1\n// g() -> 5\n// x() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive.sol b/examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive.sol new file mode 100644 index 00000000..a69a26f5 --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive.sol @@ -0,0 +1,14 @@ +contract C { + uint public called; + modifier mod1 { + called++; + _; + } + function f(uint x) public mod1 returns (uint256 r) { + return x == 0 ? 2 : f(x - 1)**2; + } +} +// ---- +// called() -> 0x00 +// f(uint256): 5 -> 0x0100000000 +// called() -> 6 diff --git a/examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive_standard_input.json b/examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive_standard_input.json new file mode 100644 index 00000000..ea8649da --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifer_recursive/modifer_recursive_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice.sol b/examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice.sol new file mode 100644 index 00000000..136743d5 --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice.sol @@ -0,0 +1,5 @@ +// The IR of this contract used to throw +contract A { modifier m1{_;} } +contract B is A { constructor() A() m1{} } +// ---- +// constructor() -> diff --git a/examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice_standard_input.json b/examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice_standard_input.json new file mode 100644 index 00000000..2f93f31f --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifier_in_constructor_ice/modifier_in_constructor_ice_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + }, + "modifier_in_constructor_ice.sol": { + "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return.sol b/examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return.sol new file mode 100644 index 00000000..d4c72e16 --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return.sol @@ -0,0 +1,12 @@ +contract C { + modifier m(bool condition) { + if (condition) _; + } + + function f(uint x) public m(x >= 10) returns (uint[5] memory r) { + r[2] = 3; + } +} +// ---- +// f(uint256): 9 -> 0x00, 0x00, 0x00, 0x00, 0x00 +// f(uint256): 10 -> 0x00, 0x00, 3, 0x00, 0x00 diff --git a/examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return_standard_input.json b/examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return_standard_input.json new file mode 100644 index 00000000..bcdce017 --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifier_init_return/modifier_init_return_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + }, + "function_modifier_loop.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f() -> 10\n" + }, + "modifer_recursive.sol": { + "content": "contract C {\n uint public called;\n modifier mod1 {\n called++;\n _;\n }\n function f(uint x) public mod1 returns (uint256 r) {\n return x == 0 ? 2 : f(x - 1)**2;\n }\n}\n// ----\n// called() -> 0x00\n// f(uint256): 5 -> 0x0100000000\n// called() -> 6\n" + }, + "modifier_in_constructor_ice.sol": { + "content": "// The IR of this contract used to throw\ncontract A { modifier m1{_;} }\ncontract B is A { constructor() A() m1{} }\n// ----\n// constructor() ->\n" + }, + "function_return_parameter_complex.sol": { + "content": "// Test to see if the function return parameter, when forwarded to the modifier actually has value\n// zero.\ncontract A {\n uint public x = 0;\n\n modifier alwaysZeros(uint256 a, uint256 b) {\n x++;\n _;\n require(a == 0, \"a is not zero\");\n require(b == 0, \"b is not zero\");\n }\n\n function f() public alwaysZeros(r1, r3) returns(uint r1, uint r2, uint r3) {\n r1 = 16;\n r2 = 32;\n r3 = 64;\n }\n\n function shouldFail(uint i1) public alwaysZeros(i1, r + 20) returns (uint r) {\n r = 0;\n }\n\n // The value of x would be 1 before calling this. It gets incremented four times in total during\n // the modifier calls\n function g() alwaysZeros(r, r) alwaysZeros(r, r) alwaysZeros(r + r, r - r) alwaysZeros(r * r, r & r) public returns (uint r) {\n r = x;\n }\n}\n// ----\n// f() -> 0x10, 0x20, 0x40\n// x() -> 1\n// shouldFail(uint256): 1 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"a is not zero\"\n// shouldFail(uint256): 0 -> FAILURE, hex\"08c379a0\", 0x20, 13, \"b is not zero\"\n// x() -> 1\n// g() -> 5\n// x() -> 5\n" + }, + "function_modifier_multiple_times_local_vars.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n uint256 b = x;\n a += b;\n _;\n a -= b;\n assert(b == x);\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 0\n" + }, + "function_modifier_library.sol": { + "content": "library L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "function_modifier_multi_invocation_viair.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 1\n" + }, + "modifier_init_return.sol": { + "content": "contract C {\n modifier m(bool condition) {\n if (condition) _;\n }\n\n function f(uint x) public m(x >= 10) returns (uint[5] memory r) {\n r[2] = 3;\n }\n}\n// ----\n// f(uint256): 9 -> 0x00, 0x00, 0x00, 0x00, 0x00\n// f(uint256): 10 -> 0x00, 0x00, 3, 0x00, 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context.sol b/examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context.sol new file mode 100644 index 00000000..30cce5a7 --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context.sol @@ -0,0 +1,11 @@ +// The IR of this contract used to throw +contract A { + constructor() m1 { } + modifier m1 { _; } +} +contract B is A { + modifier m2 { _; } + constructor() A() m1 m2 { } +} +// ---- +// constructor() -> diff --git a/examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context_standard_input.json b/examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context_standard_input.json new file mode 100644 index 00000000..5e0e2904 --- /dev/null +++ b/examples/test/semanticTests/modifiers_modifiers_in_construction_context/modifiers_in_construction_context_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + }, + "function_modifier_for_constructor.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n data |= 2;\n }\n\n modifier mod1 virtual {\n data |= 1;\n _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n data |= 4;\n _;\n }\n}\n// ----\n// getData() -> 6\n" + }, + "continue_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n if (i % 2 == 1) continue;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 5\n" + }, + "function_modifier_calling_functions_in_creation_context.sol": { + "content": "contract A {\n uint256 data;\n\n constructor() mod1 {\n f1();\n }\n\n function f1() public mod2 {\n data |= 0x1;\n }\n\n function f2() public {\n data |= 0x20;\n }\n\n function f3() public virtual {}\n\n modifier mod1 virtual {\n f2();\n _;\n }\n modifier mod2 {\n f3();\n if (false) _;\n }\n\n function getData() public returns (uint256 r) {\n return data;\n }\n}\n\n\ncontract C is A {\n modifier mod1 override {\n f4();\n _;\n }\n\n function f3() public override {\n data |= 0x300;\n }\n\n function f4() public {\n data |= 0x4000;\n }\n}\n// ----\n// getData() -> 0x4300\n" + }, + "modifiers_in_construction_context.sol": { + "content": "// The IR of this contract used to throw\ncontract A {\n constructor() m1 { }\n modifier m1 { _; }\n}\ncontract B is A {\n modifier m2 { _; }\n constructor() A() m1 m2 { }\n}\n// ----\n// constructor() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier.sol b/examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier.sol new file mode 100644 index 00000000..0d9bbfe3 --- /dev/null +++ b/examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier.sol @@ -0,0 +1,15 @@ +contract C { + uint256 public x; + modifier setsx { + _; + x = 9; + } + + function f() public setsx returns (uint256) { + return 2; + } +} +// ---- +// x() -> 0 +// f() -> 2 +// x() -> 9 diff --git a/examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier_standard_input.json b/examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier_standard_input.json new file mode 100644 index 00000000..4135d9fe --- /dev/null +++ b/examples/test/semanticTests/modifiers_return_does_not_skip_modifier/return_does_not_skip_modifier_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + }, + "access_through_contract_name.sol": { + "content": "contract A {\n uint public x = 7;\n modifier m virtual { x = 2; _; }\n}\ncontract C is A {\n modifier m override { x = 1; _; }\n\n function f() public A.m returns (uint) {\n return 9;\n }\n function g() public m returns (uint) {\n return 10;\n }\n}\n// ----\n// x() -> 7\n// f() -> 9\n// x() -> 2\n// g() -> 0x0a\n// x() -> 1\n// f() -> 9\n// x() -> 2\n" + }, + "function_modifier_local_variables.sol": { + "content": "contract C {\n modifier mod1 {\n uint8 a = 1;\n uint8 b = 2;\n _;\n }\n modifier mod2(bool a) {\n if (a) return;\n else _;\n }\n\n function f(bool a) public mod1 mod2(a) returns (uint256 r) {\n return 3;\n }\n}\n// ----\n// f(bool): true -> 0\n// f(bool): false -> 3\n" + }, + "function_modifier_overriding.sol": { + "content": "contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual {\n _;\n }\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "access_through_module_name.sol": { + "content": "==== Source: a ====\nimport \"a\" as M;\ncontract C {\n uint public x;\n modifier m { x = 1; _; }\n\n function f() public M.M.C.m returns (uint t, uint r) {\n t = x;\n x = 3;\n r = 9;\n }\n function g() public m returns (uint t, uint r) {\n t = x;\n x = 4;\n r = 10;\n }\n}\n// ----\n// x() -> 0x00\n// f() -> 1, 9\n// x() -> 3\n// g() -> 1, 0x0a\n// x() -> 4\n// f() -> 1, 9\n// x() -> 3\n" + }, + "function_modifier.sol": { + "content": "contract C {\n function getOne() public payable nonFree returns (uint256 r) {\n return 1;\n }\n\n modifier nonFree {\n if (msg.value > 0) _;\n }\n}\n// ----\n// getOne() -> 0\n// getOne(), 1 wei -> 1\n" + }, + "evaluation_order.sol": { + "content": "contract A { constructor(uint) {} }\ncontract B { constructor(uint) {} }\ncontract C { constructor(uint) {} }\n\ncontract D is A, B, C {\n uint[] x;\n constructor() m2(f(1)) B(f(2)) m1(f(3)) C(f(4)) m3(f(5)) A(f(6)) {\n f(7);\n }\n\n function query() public view returns (uint[] memory) { return x; }\n\n modifier m1(uint) { _; }\n modifier m2(uint) { _; }\n modifier m3(uint) { _; }\n\n function f(uint y) internal returns (uint) { x.push(y); return 0; }\n}\n// ----\n// query() -> 0x20, 7, 4, 2, 6, 1, 3, 5, 7\n" + }, + "function_modifier_multiple_times.sol": { + "content": "contract C {\n uint256 public a;\n modifier mod(uint256 x) {\n a += x;\n _;\n }\n\n function f(uint256 x) public mod(2) mod(5) mod(x) returns (uint256) {\n return a;\n }\n}\n// ----\n// f(uint256): 3 -> 10\n// a() -> 10\n" + }, + "function_return_parameter.sol": { + "content": "// The IR of this contract used to throw\ncontract B {\n function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }\n modifier mod1(uint a, bool b) { if (b) _; }\n modifier mod2(bytes7 a) { while (a == \"1234567\") _; }\n}\n// ----\n// f(uint8): 5 -> 0x00\n" + }, + "function_modifier_return_reference.sol": { + "content": "contract C {\n modifier m1(uint value) {\n _;\n }\n modifier m2(uint value) {\n _;\n }\n\n function f() public m1(x = 2) m2(y = 3) returns (uint x, uint y) {\n }\n}\n// ----\n// f() -> 2, 3\n" + }, + "break_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n if (i == 1)\n break;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 2\n" + }, + "function_modifier_multi_invocation.sol": { + "content": "contract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "return_does_not_skip_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier setsx {\n _;\n x = 9;\n }\n\n function f() public setsx returns (uint256) {\n return 2;\n }\n}\n// ----\n// x() -> 0\n// f() -> 2\n// x() -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier.sol b/examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier.sol new file mode 100644 index 00000000..00e2bb32 --- /dev/null +++ b/examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier.sol @@ -0,0 +1,19 @@ +contract C { + uint256 public x; + modifier run() { + for (uint256 i = 1; i < 10; i++) { + if (i == 5) return; + _; + } + } + + function f() public run { + uint256 k = x; + uint256 t = k + 1; + x = t; + } +} +// ---- +// x() -> 0 +// f() -> +// x() -> 4 diff --git a/examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier_standard_input.json b/examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier_standard_input.json new file mode 100644 index 00000000..6c5551ba --- /dev/null +++ b/examples/test/semanticTests/modifiers_return_in_modifier/return_in_modifier_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers.sol b/examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers.sol new file mode 100644 index 00000000..616a2183 --- /dev/null +++ b/examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers.sol @@ -0,0 +1,21 @@ +contract C { + uint256 public x; + modifier m() { + for (uint256 i = 0; i < 10; i++) { + _; + ++x; + return; + } + } + + function f() public m m m returns (uint) { + for (uint256 i = 0; i < 10; i++) { + ++x; + return 42; + } + } +} +// ---- +// x() -> 0 +// f() -> 42 +// x() -> 4 diff --git a/examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers_standard_input.json b/examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers_standard_input.json new file mode 100644 index 00000000..e148f37e --- /dev/null +++ b/examples/test/semanticTests/modifiers_stacked_return_with_modifiers/stacked_return_with_modifiers_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + }, + "function_modifier_loop_viair.sol": { + "content": "contract C {\n modifier repeat(uint256 count) {\n uint256 i;\n for (i = 0; i < count; ++i) _;\n }\n\n function f() public repeat(10) returns (uint256 r) {\n r += 1;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 1\n" + }, + "stacked_return_with_modifiers.sol": { + "content": "contract C {\n uint256 public x;\n modifier m() {\n for (uint256 i = 0; i < 10; i++) {\n _;\n ++x;\n return;\n }\n }\n\n function f() public m m m returns (uint) {\n for (uint256 i = 0; i < 10; i++) {\n ++x;\n return 42;\n }\n }\n}\n// ----\n// x() -> 0\n// f() -> 42\n// x() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type.sol b/examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type.sol new file mode 100644 index 00000000..2d4157ec --- /dev/null +++ b/examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type.sol @@ -0,0 +1,18 @@ +contract C { + uint16 transient x; + + modifier m(uint16) { + x += 10; + _; + } + + function f() public m(x) returns (uint16) { + x *= 10; + return x; + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 100 diff --git a/examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type_standard_input.json b/examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type_standard_input.json new file mode 100644 index 00000000..c2e82b90 --- /dev/null +++ b/examples/test/semanticTests/modifiers_transient_state_variable_value_type/transient_state_variable_value_type_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "function_modifier_empty.sol": { + "content": "abstract contract A {\n function f() public mod returns (bool r) {\n return true;\n }\n\n modifier mod virtual;\n}\n\n\ncontract C is A {\n modifier mod override {\n if (false) _;\n }\n}\n// ----\n// f() -> false\n" + }, + "return_in_modifier.sol": { + "content": "contract C {\n uint256 public x;\n modifier run() {\n for (uint256 i = 1; i < 10; i++) {\n if (i == 5) return;\n _;\n }\n }\n\n function f() public run {\n uint256 k = x;\n uint256 t = k + 1;\n x = t;\n }\n}\n// ----\n// x() -> 0\n// f() ->\n// x() -> 4\n" + }, + "function_modifier_multi_with_return.sol": { + "content": "// Note that return sets the return variable and jumps to the end of the current function or\n// modifier code block.\ncontract C {\n modifier repeat(bool twice) {\n if (twice) _;\n _;\n }\n\n function f(bool twice) public repeat(twice) returns (uint256 r) {\n r += 1;\n return r;\n }\n}\n// via yul disabled because the return variables are\n// fresh variables each time, while in the old code generator,\n// they share a stack slot when the function is\n// invoked multiple times via `_`.\n\n// ====\n// compileViaYul: false\n// ----\n// f(bool): false -> 1\n// f(bool): true -> 2\n" + }, + "function_modifier_library_inheritance.sol": { + "content": "// Tests that virtual lookup for modifiers in libraries does not consider\n// the current inheritance hierarchy.\nlibrary L {\n struct S {\n uint256 v;\n }\n modifier mod(S storage s) {\n s.v++;\n _;\n }\n\n function libFun(S storage s) internal mod(s) {\n s.v += 0x100;\n }\n}\n\n\ncontract Test {\n using L for *;\n L.S s;\n modifier mod(L.S storage) {\n revert();\n _;\n }\n\n function f() public returns (uint256) {\n s.libFun();\n L.libFun(s);\n return s.v;\n }\n}\n// ----\n// f() -> 0x202\n" + }, + "transient_state_variable_value_type.sol": { + "content": "contract C {\n uint16 transient x;\n\n modifier m(uint16) {\n x += 10;\n _;\n }\n\n function f() public m(x) returns (uint16) {\n x *= 10;\n return x;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 100\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_circular_import/circular_import.sol b/examples/test/semanticTests/multiSource_circular_import/circular_import.sol new file mode 100644 index 00000000..4c4ba4b2 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_import/circular_import.sol @@ -0,0 +1,13 @@ +==== Source: s1.sol ==== +import {f as g} from "s2.sol"; +function f() pure returns (uint) { return 1; } +==== Source: s2.sol ==== +import {f as g} from "s1.sol"; +function f() pure returns (uint) { return 2; } +contract C { + function foo() public pure returns (uint) { + return f() - g(); + } +} +// ---- +// foo() -> 1 diff --git a/examples/test/semanticTests/multiSource_circular_import/circular_import_standard_input.json b/examples/test/semanticTests/multiSource_circular_import/circular_import_standard_input.json new file mode 100644 index 00000000..b0717416 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_import/circular_import_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "free_different_interger_types.sol": { + "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint, bool) {\n return (g(2), g(false));\n }\n}\n// ----\n// foo() -> 24, true\n" + }, + "imported_free_function_via_alias_direct_call.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 6; }\ncontract D {\n function h() public pure returns (uint) {\n return g() + f() * 10000;\n }\n}\n// ----\n// h() -> 61337\n" + }, + "circular_reimport_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return 10000 + f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x2324\n" + }, + "circular_import.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g();\n }\n}\n// ----\n// foo() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_circular_import_2/circular_import_2.sol b/examples/test/semanticTests/multiSource_circular_import_2/circular_import_2.sol new file mode 100644 index 00000000..63962937 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_import_2/circular_import_2.sol @@ -0,0 +1,14 @@ +==== Source: s1.sol ==== +import {f as g, g as h} from "s2.sol"; +function f() pure returns (uint) { return 1000 + g() - h(); } +==== Source: s2.sol ==== +import {f as h} from "s1.sol"; +function f() pure returns (uint) { return 2; } +function g() pure returns (uint) { return 4; } +contract C { + function foo() public pure returns (uint) { + return h() - f() - g(); + } +} +// ---- +// foo() -> 992 diff --git a/examples/test/semanticTests/multiSource_circular_import_2/circular_import_2_standard_input.json b/examples/test/semanticTests/multiSource_circular_import_2/circular_import_2_standard_input.json new file mode 100644 index 00000000..b8742d85 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_import_2/circular_import_2_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_circular_reimport/circular_reimport.sol b/examples/test/semanticTests/multiSource_circular_reimport/circular_reimport.sol new file mode 100644 index 00000000..a866b0f5 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_reimport/circular_reimport.sol @@ -0,0 +1,16 @@ +==== Source: s1.sol ==== +import {f as g, g as h} from "s2.sol"; +function f() pure returns (uint) { return 100 + h() - g(); } +==== Source: s2.sol ==== +import {f as h} from "s1.sol"; +function f() pure returns (uint) { return 2; } +function g() pure returns (uint) { return 4; } +==== Source: s3.sol ==== +import "s1.sol"; +contract C { + function foo() public pure returns (uint) { + return f() - g() - h(); + } +} +// ---- +// foo() -> 0x60 diff --git a/examples/test/semanticTests/multiSource_circular_reimport/circular_reimport_standard_input.json b/examples/test/semanticTests/multiSource_circular_reimport/circular_reimport_standard_input.json new file mode 100644 index 00000000..07db65f7 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_reimport/circular_reimport_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2.sol b/examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2.sol new file mode 100644 index 00000000..3ff3a1a6 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2.sol @@ -0,0 +1,16 @@ +==== Source: s1.sol ==== +import {f as g, g as h} from "s2.sol"; +function f() pure returns (uint) { return 1000 + h() - g(); } +==== Source: s2.sol ==== +import {f as h} from "s1.sol"; +function f() pure returns (uint) { return 2; } +function g() pure returns (uint) { return 4; } +==== Source: s3.sol ==== +import "s2.sol"; +contract C { + function foo() public pure returns (uint) { + return 10000 + f() - g() - h(); + } +} +// ---- +// foo() -> 0x2324 diff --git a/examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2_standard_input.json b/examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2_standard_input.json new file mode 100644 index 00000000..39a03167 --- /dev/null +++ b/examples/test/semanticTests/multiSource_circular_reimport_2/circular_reimport_2_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "free_different_interger_types.sol": { + "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint, bool) {\n return (g(2), g(false));\n }\n}\n// ----\n// foo() -> 24, true\n" + }, + "imported_free_function_via_alias_direct_call.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 6; }\ncontract D {\n function h() public pure returns (uint) {\n return g() + f() * 10000;\n }\n}\n// ----\n// h() -> 61337\n" + }, + "circular_reimport_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return 10000 + f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x2324\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types.sol b/examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types.sol new file mode 100644 index 00000000..a103ef07 --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types.sol @@ -0,0 +1,12 @@ +==== Source: s1.sol ==== +function f(uint24) pure returns (uint) { return 24; } +function g(bool) pure returns (bool) { return true; } +==== Source: s2.sol ==== +import {f as g, g as g} from "s1.sol"; +contract C { + function foo() public pure returns (uint, bool) { + return (g(2), g(false)); + } +} +// ---- +// foo() -> 24, true diff --git a/examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types_standard_input.json b/examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types_standard_input.json new file mode 100644 index 00000000..c7cb09e5 --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_different_interger_types/free_different_interger_types_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "free_different_interger_types.sol": { + "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint, bool) {\n return (g(2), g(false));\n }\n}\n// ----\n// foo() -> 24, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract.sol b/examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract.sol new file mode 100644 index 00000000..321e16ae --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract.sol @@ -0,0 +1,16 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +contract C { + function g() public pure returns (uint) { + return f(); + } +} +==== Source: s2.sol ==== +import "s1.sol"; +contract D is C { + function h() public pure returns (uint) { + return g(); + } +} +// ---- +// h() -> 1337 diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract_standard_input.json b/examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract_standard_input.json new file mode 100644 index 00000000..ab6c5fea --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_base_contract/free_function_resolution_base_contract_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual.sol b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual.sol new file mode 100644 index 00000000..f111273d --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual.sol @@ -0,0 +1,16 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +contract C { + function g() public pure virtual returns (uint) { + return f() + 1; + } +} +==== Source: s2.sol ==== +import "s1.sol"; +contract D is C { + function g() public pure override returns (uint) { + return f(); + } +} +// ---- +// g() -> 1337 diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual_standard_input.json b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual_standard_input.json new file mode 100644 index 00000000..1d1794d6 --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual/free_function_resolution_override_virtual_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super.sol b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super.sol new file mode 100644 index 00000000..ae802d7c --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super.sol @@ -0,0 +1,16 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +contract C { + function g() public pure virtual returns (uint) { + return f(); + } +} +==== Source: s2.sol ==== +import "s1.sol"; +contract D is C { + function g() public pure override returns (uint) { + return super.g(); + } +} +// ---- +// g() -> 1337 diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super_standard_input.json b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super_standard_input.json new file mode 100644 index 00000000..a7f37b6a --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_super/free_function_resolution_override_virtual_super_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive.sol b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive.sol new file mode 100644 index 00000000..71723f0f --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive.sol @@ -0,0 +1,23 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +contract C { + function g() public pure virtual returns (uint) { + return f(); + } +} +==== Source: s2.sol ==== +import "s1.sol"; +contract D is C { + function g() public pure virtual override returns (uint) { + return super.g() + 1; + } +} +==== Source: s3.sol ==== +import "s2.sol"; +contract E is D { + function g() public pure override returns (uint) { + return super.g() + 1; + } +} +// ---- +// g() -> 1339 diff --git a/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive_standard_input.json b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive_standard_input.json new file mode 100644 index 00000000..d9381b6e --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_resolution_override_virtual_transitive/free_function_resolution_override_virtual_transitive_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import.sol b/examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import.sol new file mode 100644 index 00000000..dec4c3f2 --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import.sol @@ -0,0 +1,24 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +contract C { + function g() public pure returns (uint) { + return f(); + } +} +==== Source: s2.sol ==== +import "s1.sol"; +contract D is C { + function h() public pure returns (uint) { + return g(); + } +} +==== Source: s3.sol ==== +import "s2.sol"; +import {f as f} from "s2.sol"; +contract E is D { + function i() public pure returns (uint) { + return f(); + } +} +// ---- +// i() -> 1337 diff --git a/examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import_standard_input.json b/examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import_standard_input.json new file mode 100644 index 00000000..f19dd128 --- /dev/null +++ b/examples/test/semanticTests/multiSource_free_function_transitive_import/free_function_transitive_import_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_import/import.sol b/examples/test/semanticTests/multiSource_import/import.sol new file mode 100644 index 00000000..2a0f43d5 --- /dev/null +++ b/examples/test/semanticTests/multiSource_import/import.sol @@ -0,0 +1,12 @@ +==== Source: A ==== +contract A { + function g(uint256 x) public view returns(uint256) { return x + 1; } +} +==== Source: B ==== +import "A"; +contract B is A { + function f(uint256 x) public view returns(uint256) { return x; } +} +// ---- +// f(uint256): 1337 -> 1337 +// g(uint256): 1337 -> 1338 diff --git a/examples/test/semanticTests/multiSource_import/import_standard_input.json b/examples/test/semanticTests/multiSource_import/import_standard_input.json new file mode 100644 index 00000000..d3f6b3d0 --- /dev/null +++ b/examples/test/semanticTests/multiSource_import/import_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function.sol b/examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function.sol new file mode 100644 index 00000000..8d714dd4 --- /dev/null +++ b/examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function.sol @@ -0,0 +1,13 @@ +==== Source: A ==== +function sub(uint256 x, uint256 y) pure returns (uint) { return 1; } +function sub(uint256 x) pure returns (uint) { return 2; } +==== Source: B ==== +import {sub} from "A"; +contract C +{ + function f() public pure returns (uint, uint) { + return (sub(1, 2), sub(2)); + } +} +// ---- +// f() -> 1, 2 diff --git a/examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function_standard_input.json b/examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function_standard_input.json new file mode 100644 index 00000000..db4dc5e0 --- /dev/null +++ b/examples/test/semanticTests/multiSource_import_overloaded_function/import_overloaded_function_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias.sol b/examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias.sol new file mode 100644 index 00000000..c5769367 --- /dev/null +++ b/examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias.sol @@ -0,0 +1,17 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +contract C { + function g() public pure virtual returns (uint) { + return f(); + } +} +==== Source: s2.sol ==== +import "s1.sol" as M; +function f() pure returns (uint) { return 6; } +contract D is M.C { + function g() public pure override returns (uint) { + return super.g() + f() * 10000; + } +} +// ---- +// g() -> 61337 diff --git a/examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias_standard_input.json b/examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias_standard_input.json new file mode 100644 index 00000000..83715e6a --- /dev/null +++ b/examples/test/semanticTests/multiSource_imported_free_function_via_alias/imported_free_function_via_alias_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "free_different_interger_types.sol": { + "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint, bool) {\n return (g(2), g(false));\n }\n}\n// ----\n// foo() -> 24, true\n" + }, + "imported_free_function_via_alias_direct_call.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 6; }\ncontract D {\n function h() public pure returns (uint) {\n return g() + f() * 10000;\n }\n}\n// ----\n// h() -> 61337\n" + }, + "circular_reimport_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return 10000 + f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x2324\n" + }, + "circular_import.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g();\n }\n}\n// ----\n// foo() -> 1\n" + }, + "reimport_imported_function.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\nimport {g as h} from \"s2.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return h();\n }\n}\n// ----\n// foo() -> 1337\n" + }, + "imported_free_function_via_alias.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\nfunction f() pure returns (uint) { return 6; }\ncontract D is M.C {\n function g() public pure override returns (uint) {\n return super.g() + f() * 10000;\n }\n}\n// ----\n// g() -> 61337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call.sol b/examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call.sol new file mode 100644 index 00000000..a5f43f8b --- /dev/null +++ b/examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call.sol @@ -0,0 +1,12 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +==== Source: s2.sol ==== +import {f as g} from "s1.sol"; +function f() pure returns (uint) { return 6; } +contract D { + function h() public pure returns (uint) { + return g() + f() * 10000; + } +} +// ---- +// h() -> 61337 diff --git a/examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call_standard_input.json b/examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call_standard_input.json new file mode 100644 index 00000000..802ca691 --- /dev/null +++ b/examples/test/semanticTests/multiSource_imported_free_function_via_alias_direct_call/imported_free_function_via_alias_direct_call_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "free_different_interger_types.sol": { + "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint, bool) {\n return (g(2), g(false));\n }\n}\n// ----\n// foo() -> 24, true\n" + }, + "imported_free_function_via_alias_direct_call.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 6; }\ncontract D {\n function h() public pure returns (uint) {\n return g() + f() * 10000;\n }\n}\n// ----\n// h() -> 61337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function.sol b/examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function.sol new file mode 100644 index 00000000..02b48214 --- /dev/null +++ b/examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function.sol @@ -0,0 +1,13 @@ +==== Source: s1.sol ==== +function f() pure returns (uint) { return 1337; } +==== Source: s2.sol ==== +import {f as g} from "s1.sol"; +==== Source: s3.sol ==== +import {g as h} from "s2.sol"; +contract C { + function foo() public pure returns (uint) { + return h(); + } +} +// ---- +// foo() -> 1337 diff --git a/examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function_standard_input.json b/examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function_standard_input.json new file mode 100644 index 00000000..46544d2f --- /dev/null +++ b/examples/test/semanticTests/multiSource_reimport_imported_function/reimport_imported_function_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "free_function_transitive_import.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\nimport {f as f} from \"s2.sol\";\ncontract E is D {\n function i() public pure returns (uint) {\n return f();\n }\n}\n// ----\n// i() -> 1337\n" + }, + "import.sol": { + "content": "==== Source: A ====\ncontract A {\n\tfunction g(uint256 x) public view returns(uint256) { return x + 1; }\n}\n==== Source: B ====\nimport \"A\";\ncontract B is A {\n\tfunction f(uint256 x) public view returns(uint256) { return x; }\n}\n// ----\n// f(uint256): 1337 -> 1337\n// g(uint256): 1337 -> 1338\n" + }, + "free_function_resolution_override_virtual.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f() + 1;\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return f();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "circular_reimport.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 100 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x60\n" + }, + "circular_import_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + g() - h(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\ncontract C {\n function foo() public pure returns (uint) {\n return h() - f() - g();\n }\n}\n// ----\n// foo() -> 992\n" + }, + "free_function_resolution_base_contract.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function h() public pure returns (uint) {\n return g();\n }\n}\n// ----\n// h() -> 1337\n" + }, + "free_function_resolution_override_virtual_transitive.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure virtual override returns (uint) {\n return super.g() + 1;\n }\n}\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract E is D {\n function g() public pure override returns (uint) {\n return super.g() + 1;\n }\n}\n// ----\n// g() -> 1339\n" + }, + "import_overloaded_function.sol": { + "content": "==== Source: A ====\nfunction sub(uint256 x, uint256 y) pure returns (uint) { return 1; }\nfunction sub(uint256 x) pure returns (uint) { return 2; }\n==== Source: B ====\nimport {sub} from \"A\";\ncontract C\n{\n function f() public pure returns (uint, uint) {\n return (sub(1, 2), sub(2));\n }\n}\n// ----\n// f() -> 1, 2\n" + }, + "free_function_resolution_override_virtual_super.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\ncontract C {\n function g() public pure virtual returns (uint) {\n return f();\n }\n}\n==== Source: s2.sol ====\nimport \"s1.sol\";\ncontract D is C {\n function g() public pure override returns (uint) {\n return super.g();\n }\n}\n// ----\n// g() -> 1337\n" + }, + "free_different_interger_types.sol": { + "content": "==== Source: s1.sol ====\nfunction f(uint24) pure returns (uint) { return 24; }\nfunction g(bool) pure returns (bool) { return true; }\n==== Source: s2.sol ====\nimport {f as g, g as g} from \"s1.sol\";\ncontract C {\n function foo() public pure returns (uint, bool) {\n return (g(2), g(false));\n }\n}\n// ----\n// foo() -> 24, true\n" + }, + "imported_free_function_via_alias_direct_call.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 6; }\ncontract D {\n function h() public pure returns (uint) {\n return g() + f() * 10000;\n }\n}\n// ----\n// h() -> 61337\n" + }, + "circular_reimport_2.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g, g as h} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1000 + h() - g(); }\n==== Source: s2.sol ====\nimport {f as h} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\nfunction g() pure returns (uint) { return 4; }\n==== Source: s3.sol ====\nimport \"s2.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return 10000 + f() - g() - h();\n }\n}\n// ----\n// foo() -> 0x2324\n" + }, + "circular_import.sol": { + "content": "==== Source: s1.sol ====\nimport {f as g} from \"s2.sol\";\nfunction f() pure returns (uint) { return 1; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\nfunction f() pure returns (uint) { return 2; }\ncontract C {\n function foo() public pure returns (uint) {\n return f() - g();\n }\n}\n// ----\n// foo() -> 1\n" + }, + "reimport_imported_function.sol": { + "content": "==== Source: s1.sol ====\nfunction f() pure returns (uint) { return 1337; }\n==== Source: s2.sol ====\nimport {f as g} from \"s1.sol\";\n==== Source: s3.sol ====\nimport {g as h} from \"s2.sol\";\ncontract C {\n function foo() public pure returns (uint) {\n return h();\n }\n}\n// ----\n// foo() -> 1337\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_compound_assign/compound_assign.sol b/examples/test/semanticTests/operators_compound_assign/compound_assign.sol new file mode 100644 index 00000000..ed91f3b6 --- /dev/null +++ b/examples/test/semanticTests/operators_compound_assign/compound_assign.sol @@ -0,0 +1,20 @@ +contract test { + uint value1; + uint value2; + function f(uint x, uint y) public returns (uint w) { + uint value3 = y; + value1 += x; + value3 *= x; + value2 *= value3 + value1; + return value2 += 7; + } +} +// ---- +// f(uint256,uint256): 0, 6 -> 7 +// f(uint256,uint256): 1, 3 -> 0x23 +// f(uint256,uint256): 2, 25 -> 0x0746 +// f(uint256,uint256): 3, 69 -> 396613 +// f(uint256,uint256): 4, 84 -> 137228105 +// f(uint256,uint256): 5, 2 -> 0xcc7c5e28 +// f(uint256,uint256): 6, 51 -> 1121839760671 +// f(uint256,uint256): 7, 48 -> 408349672884251 diff --git a/examples/test/semanticTests/operators_compound_assign/compound_assign_standard_input.json b/examples/test/semanticTests/operators_compound_assign/compound_assign_standard_input.json new file mode 100644 index 00000000..2cd39f2e --- /dev/null +++ b/examples/test/semanticTests/operators_compound_assign/compound_assign_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "compound_assign_transient_storage.sol": { + "content": "contract test {\n\tuint value1;\n\tuint transient value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 += value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 11\n// f(uint256,uint256): 2, 25 -> 0x3c\n// f(uint256,uint256): 3, 69 -> 0xdc\n// f(uint256,uint256): 4, 84 -> 353\n// f(uint256,uint256): 5, 2 -> 0x20\n// f(uint256,uint256): 6, 51 -> 334\n// f(uint256,uint256): 7, 48 -> 371\n" + }, + "compound_assign.sol": { + "content": "contract test {\n\tuint value1;\n\tuint value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 *= value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 0x23\n// f(uint256,uint256): 2, 25 -> 0x0746\n// f(uint256,uint256): 3, 69 -> 396613\n// f(uint256,uint256): 4, 84 -> 137228105\n// f(uint256,uint256): 5, 2 -> 0xcc7c5e28\n// f(uint256,uint256): 6, 51 -> 1121839760671\n// f(uint256,uint256): 7, 48 -> 408349672884251\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage.sol b/examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage.sol new file mode 100644 index 00000000..c3adf3a1 --- /dev/null +++ b/examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage.sol @@ -0,0 +1,22 @@ +contract test { + uint value1; + uint transient value2; + function f(uint x, uint y) public returns (uint w) { + uint value3 = y; + value1 += x; + value3 *= x; + value2 += value3 + value1; + return value2 += 7; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f(uint256,uint256): 0, 6 -> 7 +// f(uint256,uint256): 1, 3 -> 11 +// f(uint256,uint256): 2, 25 -> 0x3c +// f(uint256,uint256): 3, 69 -> 0xdc +// f(uint256,uint256): 4, 84 -> 353 +// f(uint256,uint256): 5, 2 -> 0x20 +// f(uint256,uint256): 6, 51 -> 334 +// f(uint256,uint256): 7, 48 -> 371 diff --git a/examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage_standard_input.json b/examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage_standard_input.json new file mode 100644 index 00000000..3dae5dac --- /dev/null +++ b/examples/test/semanticTests/operators_compound_assign_transient_storage/compound_assign_transient_storage_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "compound_assign_transient_storage.sol": { + "content": "contract test {\n\tuint value1;\n\tuint transient value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 += value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 11\n// f(uint256,uint256): 2, 25 -> 0x3c\n// f(uint256,uint256): 3, 69 -> 0xdc\n// f(uint256,uint256): 4, 84 -> 353\n// f(uint256,uint256): 5, 2 -> 0x20\n// f(uint256,uint256): 6, 51 -> 334\n// f(uint256,uint256): 7, 48 -> 371\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople.sol b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople.sol new file mode 100644 index 00000000..e4f0834a --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople.sol @@ -0,0 +1,33 @@ +contract C { + function shl(uint256 a, uint256 b) public returns (uint256 c) { + assembly { + c := shl(b, a) + } + } + + function shr(uint256 a, uint256 b) public returns (uint256 c) { + assembly { + c := shr(b, a) + } + } + + function sar(uint256 a, uint256 b) public returns (uint256 c) { + assembly { + c := sar(b, a) + } + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// shl(uint256,uint256): 0x01, 0x02 -> 0x04 +// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00 +// shr(uint256,uint256): 0x03, 0x01 -> 0x01 +// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01 +// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00 +// sar(uint256,uint256): 0x03, 0x01 -> 0x01 +// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople_standard_input.json b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople_standard_input.json new file mode 100644 index 00000000..d5678e6b --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople/bitwise_shifting_constantinople_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined.sol b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined.sol new file mode 100644 index 00000000..6e3bb173 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined.sol @@ -0,0 +1,121 @@ +contract C { + function shl_zero(uint256 a) public returns (uint256 c) { + assembly { + c := shl(0, a) + } + } + + function shr_zero(uint256 a) public returns (uint256 c) { + assembly { + c := shr(0, a) + } + } + + function sar_zero(uint256 a) public returns (uint256 c) { + assembly { + c := sar(0, a) + } + } + + function shl_large(uint256 a) public returns (uint256 c) { + assembly { + c := shl(0x110, a) + } + } + + function shr_large(uint256 a) public returns (uint256 c) { + assembly { + c := shr(0x110, a) + } + } + + function sar_large(uint256 a) public returns (uint256 c) { + assembly { + c := sar(0x110, a) + } + } + + function shl_combined(uint256 a) public returns (uint256 c) { + assembly { + c := shl(4, shl(12, a)) + } + } + + function shr_combined(uint256 a) public returns (uint256 c) { + assembly { + c := shr(4, shr(12, a)) + } + } + + function sar_combined(uint256 a) public returns (uint256 c) { + assembly { + c := sar(4, sar(12, a)) + } + } + + function shl_combined_large(uint256 a) public returns (uint256 c) { + assembly { + c := shl(0xd0, shl(0x40, a)) + } + } + + function shl_combined_overflow(uint256 a) public returns (uint256 c) { + assembly { + c := shl(0x01, shl(not(0x00), a)) + } + } + + function shr_combined_large(uint256 a) public returns (uint256 c) { + assembly { + c := shr(0xd0, shr(0x40, a)) + } + } + + function shr_combined_overflow(uint256 a) public returns (uint256 c) { + assembly { + c := shr(0x01, shr(not(0x00), a)) + } + } + + function sar_combined_large(uint256 a) public returns (uint256 c) { + assembly { + c := sar(0xd0, sar(0x40, a)) + } + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// shl_zero(uint256): 0x00 -> 0x00 +// shl_zero(uint256): 0xffff -> 0xffff +// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// shr_zero(uint256): 0x00 -> 0x00 +// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// sar_zero(uint256): 0x00 -> 0x00 +// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// shl_large(uint256): 0x00 -> 0x00 +// shl_large(uint256): 0xffff -> 0x00 +// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// shr_large(uint256): 0x00 -> 0x00 +// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// sar_large(uint256): 0x00 -> 0x00 +// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// shl_combined(uint256): 0x00 -> 0x00 +// shl_combined(uint256): 0xffff -> 0xffff0000 +// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000 +// shr_combined(uint256): 0x00 -> 0x00 +// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// sar_combined(uint256): 0x00 -> 0x00 +// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// shl_combined_large(uint256): 0x00 -> 0x00 +// shl_combined_large(uint256): 0xffff -> 0x00 +// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// shl_combined_overflow(uint256): 0x02 -> 0x00 +// shr_combined_large(uint256): 0x00 -> 0x00 +// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// shr_combined_overflow(uint256): 0x02 -> 0x00 +// sar_combined_large(uint256): 0x00 -> 0x00 +// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00 +// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined_standard_input.json b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined_standard_input.json new file mode 100644 index 00000000..e36cf882 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constantinople_combined/bitwise_shifting_constantinople_combined_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople.sol b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople.sol new file mode 100644 index 00000000..526909c6 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople.sol @@ -0,0 +1,82 @@ +contract C { + function shl_1() public returns (bool) { + uint256 c; + assembly { + c := shl(2, 1) + } + assert(c == 4); + return true; + } + + function shl_2() public returns (bool) { + uint256 c; + assembly { + c := shl( + 1, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + } + assert( + c == + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + ); + return true; + } + + function shl_3() public returns (bool) { + uint256 c; + assembly { + c := shl( + 256, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + } + assert(c == 0); + return true; + } + + function shr_1() public returns (bool) { + uint256 c; + assembly { + c := shr(1, 3) + } + assert(c == 1); + return true; + } + + function shr_2() public returns (bool) { + uint256 c; + assembly { + c := shr( + 1, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + } + assert( + c == + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ); + return true; + } + + function shr_3() public returns (bool) { + uint256 c; + assembly { + c := shr( + 256, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + } + assert(c == 0); + return true; + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// shl_1() -> 0x01 +// shl_2() -> 0x01 +// shl_3() -> 0x01 +// shr_1() -> 0x01 +// shr_2() -> 0x01 +// shr_3() -> 0x01 diff --git a/examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople_standard_input.json b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople_standard_input.json new file mode 100644 index 00000000..47303c9d --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_bitwise_shifting_constants_constantinople/bitwise_shifting_constants_constantinople_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup.sol b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup.sol new file mode 100644 index 00000000..e8f7d074 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup.sol @@ -0,0 +1,19 @@ +contract C { + function l(uint8 y) public returns (bytes20) { + bytes20 x; + assembly { x := "12345678901234567890abcde" } + // When compiling via IR, `x` is truncated before applying + // the operation. + return x << y; + } + function r(uint8 y) public returns (bytes20) { + bytes20 x; + assembly { x := "12345678901234567890abcde" } + return x >> y; + } +} +// ==== +// compileViaYul: false +// ---- +// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000 +// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000 diff --git a/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup_standard_input.json new file mode 100644 index 00000000..65d12ec0 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup/shift_bytes_cleanup_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul.sol b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul.sol new file mode 100644 index 00000000..36b6e8b5 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul.sol @@ -0,0 +1,19 @@ +contract C { + function l(uint8 y) public returns (bytes20) { + bytes20 x; + assembly { x := "12345678901234567890abcde" } + // When compiling via IR, `x` is truncated before applying + // the operation. + return x << y; + } + function r(uint8 y) public returns (bytes20) { + bytes20 x; + assembly { x := "12345678901234567890abcde" } + return x >> y; + } +} +// ==== +// compileViaYul: true +// ---- +// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000 +// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000 diff --git a/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul_standard_input.json new file mode 100644 index 00000000..75686bfb --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_bytes_cleanup_viaYul/shift_bytes_cleanup_viaYul_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup.sol b/examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup.sol new file mode 100644 index 00000000..0adc5ae5 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup.sol @@ -0,0 +1,12 @@ +contract C { + function f() public returns (uint16 x) { + unchecked { + x = 0xffff; + x += 32; + x <<= 8; + x >>= 16; + } + } +} +// ---- +// f() -> 0x0 diff --git a/examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup_standard_input.json new file mode 100644 index 00000000..ad6ccbcb --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_cleanup/shift_cleanup_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled.sol b/examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled.sol new file mode 100644 index 00000000..452884f2 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint8 x) { + assembly { + x := 0xffff + } + x >>= 8; + } +} +// ---- +// f() -> 0x0 diff --git a/examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled_standard_input.json new file mode 100644 index 00000000..86522a0f --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_cleanup_garbled/shift_cleanup_garbled_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left.sol b/examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left.sol new file mode 100644 index 00000000..bc0c9f48 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left.sol @@ -0,0 +1,5 @@ +contract C { + uint256 public a = 0x42 << 8; +} +// ---- +// a() -> 0x4200 diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left_standard_input.json new file mode 100644 index 00000000..f0885890 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_left/shift_constant_left_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment.sol b/examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment.sol new file mode 100644 index 00000000..3d245e9b --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f() public returns (uint256 a) { + a = 0x42; + a <<= 8; + } +} +// ---- +// f() -> 0x4200 diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment_standard_input.json new file mode 100644 index 00000000..ebb52bf4 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_left_assignment/shift_constant_left_assignment_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + }, + "shift_right_negative_lvalue_signextend_int8_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_left_assignment_different_type.sol": { + "content": "contract C {\n function f(uint256 a, uint8 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint8): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint8): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n" + }, + "shift_right_garbled_signed_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xfffffff0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n\n function g(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xf0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> FAILURE\n// f(int8,uint8): 0x00, 0x1004 -> FAILURE\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> FAILURE\n// g(int8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_constant_left_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x42;\n a <<= 8;\n }\n}\n// ----\n// f() -> 0x4200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right.sol b/examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right.sol new file mode 100644 index 00000000..64403475 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right.sol @@ -0,0 +1,5 @@ +contract C { + uint256 public a = 0x4200 >> 8; +} +// ---- +// a() -> 0x42 diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right_standard_input.json new file mode 100644 index 00000000..91a96549 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_right/shift_constant_right_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment.sol b/examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment.sol new file mode 100644 index 00000000..ded331a7 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f() public returns (uint256 a) { + a = 0x4200; + a >>= 8; + } +} +// ---- +// f() -> 0x42 diff --git a/examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment_standard_input.json new file mode 100644 index 00000000..8cd4180d --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_constant_right_assignment/shift_constant_right_assignment_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_left/shift_left.sol b/examples/test/semanticTests/operators_shifts_shift_left/shift_left.sol new file mode 100644 index 00000000..47afab5e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left/shift_left.sol @@ -0,0 +1,12 @@ +contract C { + function f(uint256 a, uint256 b) public returns (uint256) { + return a << b; + } +} +// ---- +// f(uint256,uint256): 0x4266, 0x0 -> 0x4266 +// f(uint256,uint256): 0x4266, 0x8 -> 0x426600 +// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000 +// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000 +// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000 +// f(uint256,uint256): 0x4266, 0x100 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_left/shift_left_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_left/shift_left_standard_input.json new file mode 100644 index 00000000..a6b5bf8f --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left/shift_left_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment.sol b/examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment.sol new file mode 100644 index 00000000..afa82c6f --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment.sol @@ -0,0 +1,13 @@ +contract C { + function f(uint256 a, uint256 b) public returns (uint256) { + a <<= b; + return a; + } +} +// ---- +// f(uint256,uint256): 0x4266, 0x0 -> 0x4266 +// f(uint256,uint256): 0x4266, 0x8 -> 0x426600 +// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000 +// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000 +// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000 +// f(uint256,uint256): 0x4266, 0x100 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment_standard_input.json new file mode 100644 index 00000000..e49a1b72 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_assignment/shift_left_assignment_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type.sol b/examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type.sol new file mode 100644 index 00000000..44fd4a92 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type.sol @@ -0,0 +1,12 @@ +contract C { + function f(uint256 a, uint8 b) public returns (uint256) { + a <<= b; + return a; + } +} +// ---- +// f(uint256,uint8): 0x4266, 0x0 -> 0x4266 +// f(uint256,uint8): 0x4266, 0x8 -> 0x426600 +// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000 +// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000 +// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type_standard_input.json new file mode 100644 index 00000000..41124a39 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_assignment_different_type/shift_left_assignment_different_type_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + }, + "shift_right_negative_lvalue_signextend_int8_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_left_assignment_different_type.sol": { + "content": "contract C {\n function f(uint256 a, uint8 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint8): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint8): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type.sol b/examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type.sol new file mode 100644 index 00000000..3d6d7c7e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type.sol @@ -0,0 +1,10 @@ +// This basically tests proper cleanup and conversion. It should not convert x to int8. +contract C { + function f() public returns (int8) { + uint8 x = 254; + int8 y = 1; + return y << x; + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type_standard_input.json new file mode 100644 index 00000000..c029ac6e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_larger_type/shift_left_larger_type_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32.sol b/examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32.sol new file mode 100644 index 00000000..d66e2f4c --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32.sol @@ -0,0 +1,11 @@ +contract C { + function f(uint32 a, uint32 b) public returns (uint256) { + return a << b; + } +} +// ---- +// f(uint32,uint32): 0x4266, 0x0 -> 0x4266 +// f(uint32,uint32): 0x4266, 0x8 -> 0x426600 +// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000 +// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000 +// f(uint32,uint32): 0x4266, 0x20 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32_standard_input.json new file mode 100644 index 00000000..db8bdbba --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_uint32/shift_left_uint32_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8.sol b/examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8.sol new file mode 100644 index 00000000..d6d6d77b --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint8 a, uint8 b) public returns (uint256) { + return a << b; + } +} +// ---- +// f(uint8,uint8): 0x66, 0x0 -> 0x66 +// f(uint8,uint8): 0x66, 0x8 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8_standard_input.json new file mode 100644 index 00000000..ca525a1f --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_left_uint8/shift_left_uint8_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left.sol b/examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left.sol new file mode 100644 index 00000000..7671ce19 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left.sol @@ -0,0 +1,5 @@ +contract C { + int256 public a = -0x42 << 8; +} +// ---- +// a() -> -16896 diff --git a/examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left_standard_input.json new file mode 100644 index 00000000..705d1fe2 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_negative_constant_left/shift_negative_constant_left_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right.sol b/examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right.sol new file mode 100644 index 00000000..e9a76d2c --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right.sol @@ -0,0 +1,5 @@ +contract C { + int256 public a = -0x4200 >> 8; +} +// ---- +// a() -> -66 diff --git a/examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right_standard_input.json new file mode 100644 index 00000000..95091bc9 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_negative_constant_right/shift_negative_constant_right_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow.sol b/examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow.sol new file mode 100644 index 00000000..5b0491b3 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow.sol @@ -0,0 +1,15 @@ +contract C { + function leftU(uint8 x, uint8 y) public returns (uint8) { + return x << y; + } + + function leftS(int8 x, uint8 y) public returns (int8) { + return x << y; + } +} +// ---- +// leftU(uint8,uint8): 255, 8 -> 0 +// leftU(uint8,uint8): 255, 1 -> 254 +// leftU(uint8,uint8): 255, 0 -> 255 +// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. # +// leftS(int8,uint8): 1, 6 -> 64 diff --git a/examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow_standard_input.json new file mode 100644 index 00000000..94d5e753 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_overflow/shift_overflow_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right/shift_right.sol b/examples/test/semanticTests/operators_shifts_shift_right/shift_right.sol new file mode 100644 index 00000000..4947b21d --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right/shift_right.sol @@ -0,0 +1,11 @@ +contract C { + function f(uint256 a, uint256 b) public returns (uint256) { + return a >> b; + } +} +// ---- +// f(uint256,uint256): 0x4266, 0x0 -> 0x4266 +// f(uint256,uint256): 0x4266, 0x8 -> 0x42 +// f(uint256,uint256): 0x4266, 0x10 -> 0 +// f(uint256,uint256): 0x4266, 0x11 -> 0 +// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624 diff --git a/examples/test/semanticTests/operators_shifts_shift_right/shift_right_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right/shift_right_standard_input.json new file mode 100644 index 00000000..6a045a8e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right/shift_right_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment.sol b/examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment.sol new file mode 100644 index 00000000..f9206b09 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment.sol @@ -0,0 +1,11 @@ +contract C { + function f(uint256 a, uint256 b) public returns (uint256) { + a >>= b; + return a; + } +} +// ---- +// f(uint256,uint256): 0x4266, 0x0 -> 0x4266 +// f(uint256,uint256): 0x4266, 0x8 -> 0x42 +// f(uint256,uint256): 0x4266, 0x10 -> 0 +// f(uint256,uint256): 0x4266, 0x11 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment_standard_input.json new file mode 100644 index 00000000..f3f8de9e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_assignment/shift_right_assignment_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + }, + "shift_right_negative_lvalue_signextend_int8_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_left_assignment_different_type.sol": { + "content": "contract C {\n function f(uint256 a, uint8 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint8): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint8): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n" + }, + "shift_right_garbled_signed_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xfffffff0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n\n function g(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xf0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> FAILURE\n// f(int8,uint8): 0x00, 0x1004 -> FAILURE\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> FAILURE\n// g(int8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_constant_left_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x42;\n a <<= 8;\n }\n}\n// ----\n// f() -> 0x4200\n" + }, + "shift_right_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1.sol b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1.sol new file mode 100644 index 00000000..094d75b6 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1.sol @@ -0,0 +1,32 @@ +pragma abicoder v1; +contract C { + function f(int8 a, uint8 b) public returns (int256) { + assembly { + a := 0xfffffff0 + } + // Higher bits should be signextended before the shift + return a >> b; + } + + function g(int8 a, uint8 b) public returns (int256) { + assembly { + a := 0xf0 + } + // Higher bits should be signextended before the shift + return a >> b; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// f(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// g(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// g(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1_standard_input.json new file mode 100644 index 00000000..1448480d --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v1/shift_right_garbled_signed_v1_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + }, + "shift_right_negative_lvalue_signextend_int8_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_left_assignment_different_type.sol": { + "content": "contract C {\n function f(uint256 a, uint8 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint8): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint8): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n" + }, + "shift_right_garbled_signed_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xfffffff0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n\n function g(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xf0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> FAILURE\n// f(int8,uint8): 0x00, 0x1004 -> FAILURE\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> FAILURE\n// g(int8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_constant_left_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x42;\n a <<= 8;\n }\n}\n// ----\n// f() -> 0x4200\n" + }, + "shift_right_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n" + }, + "shift_right_garbled_signed_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xfffffff0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n\n function g(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xf0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x1004 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2.sol b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2.sol new file mode 100644 index 00000000..2b1afb52 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2.sol @@ -0,0 +1,31 @@ +pragma abicoder v2; + + +contract C { + function f(int8 a, uint8 b) public returns (int256) { + assembly { + a := 0xfffffff0 + } + // Higher bits should be signextended before the shift + return a >> b; + } + + function g(int8 a, uint8 b) public returns (int256) { + assembly { + a := 0xf0 + } + // Higher bits should be signextended before the shift + return a >> b; + } +} +// ---- +// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int8,uint8): 0x00, 0x1003 -> FAILURE +// f(int8,uint8): 0x00, 0x1004 -> FAILURE +// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// g(int8,uint8): 0x00, 0x1003 -> FAILURE +// g(int8,uint8): 0x00, 0x1004 -> FAILURE diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2_standard_input.json new file mode 100644 index 00000000..8ed989bb --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_signed_v2/shift_right_garbled_signed_v2_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + }, + "shift_right_negative_lvalue_signextend_int8_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_left_assignment_different_type.sol": { + "content": "contract C {\n function f(uint256 a, uint8 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint8): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint8): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint8): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint8): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint8): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n" + }, + "shift_right_garbled_signed_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xfffffff0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n\n function g(int8 a, uint8 b) public returns (int256) {\n assembly {\n a := 0xf0\n }\n // Higher bits should be signextended before the shift\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// f(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// f(int8,uint8): 0x00, 0x1003 -> FAILURE\n// f(int8,uint8): 0x00, 0x1004 -> FAILURE\n// g(int8,uint8): 0x00, 0x03 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// g(int8,uint8): 0x00, 0x04 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// g(int8,uint8): 0x00, 0x1003 -> FAILURE\n// g(int8,uint8): 0x00, 0x1004 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1.sol b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1.sol new file mode 100644 index 00000000..8412e372 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1.sol @@ -0,0 +1,16 @@ +pragma abicoder v1; +contract C { + function f(uint8 a, uint8 b) public returns (uint256) { + assembly { + a := 0xffffffff + } + // Higher bits should be cleared before the shift + return a >> b; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(uint8,uint8): 0x00, 0x04 -> 0x0f +// f(uint8,uint8): 0x00, 0x1004 -> 0x0f diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1_standard_input.json new file mode 100644 index 00000000..6604abb8 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v1/shift_right_garbled_v1_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2.sol b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2.sol new file mode 100644 index 00000000..8cf89f4b --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + + +contract C { + function f(uint8 a, uint8 b) public returns (uint256) { + assembly { + a := 0xffffffff + } + // Higher bits should be cleared before the shift + return a >> b; + } +} +// ---- +// f(uint8,uint8): 0x00, 0x04 -> 0x0f +// f(uint8,uint8): 0x00, 0x1004 -> FAILURE diff --git a/examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2_standard_input.json new file mode 100644 index 00000000..3fcfc3f4 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_garbled_v2/shift_right_garbled_v2_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal.sol new file mode 100644 index 00000000..e24118af --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal.sol @@ -0,0 +1,62 @@ +contract C { + function f1() public pure returns (bool) { + return (-4266 >> 0) == -4266; + } + + function f2() public pure returns (bool) { + return (-4266 >> 1) == -2133; + } + + function f3() public pure returns (bool) { + return (-4266 >> 4) == -267; + } + + function f4() public pure returns (bool) { + return (-4266 >> 8) == -17; + } + + function f5() public pure returns (bool) { + return (-4266 >> 16) == -1; + } + + function f6() public pure returns (bool) { + return (-4266 >> 17) == -1; + } + + function g1() public pure returns (bool) { + return (-4267 >> 0) == -4267; + } + + function g2() public pure returns (bool) { + return (-4267 >> 1) == -2134; + } + + function g3() public pure returns (bool) { + return (-4267 >> 4) == -267; + } + + function g4() public pure returns (bool) { + return (-4267 >> 8) == -17; + } + + function g5() public pure returns (bool) { + return (-4267 >> 16) == -1; + } + + function g6() public pure returns (bool) { + return (-4267 >> 17) == -1; + } +} +// ---- +// f1() -> true +// f2() -> true +// f3() -> true +// f4() -> true +// f5() -> true +// f6() -> true +// g1() -> true +// g2() -> true +// g3() -> true +// g4() -> true +// g5() -> true +// g6() -> true diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal_standard_input.json new file mode 100644 index 00000000..5e6b7b92 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_literal/shift_right_negative_literal_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue.sol new file mode 100644 index 00000000..5dcde06f --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue.sol @@ -0,0 +1,18 @@ +contract C { + function f(int256 a, uint256 b) public returns (int256) { + return a >> b; + } +} +// ---- +// f(int256,uint256): -4266, 0 -> -4266 +// f(int256,uint256): -4266, 1 -> -2133 +// f(int256,uint256): -4266, 4 -> -267 +// f(int256,uint256): -4266, 8 -> -17 +// f(int256,uint256): -4266, 16 -> -1 +// f(int256,uint256): -4266, 17 -> -1 +// f(int256,uint256): -4267, 0 -> -4267 +// f(int256,uint256): -4267, 1 -> -2134 +// f(int256,uint256): -4267, 4 -> -267 +// f(int256,uint256): -4267, 8 -> -17 +// f(int256,uint256): -4267, 16 -> -1 +// f(int256,uint256): -4267, 17 -> -1 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue_standard_input.json new file mode 100644 index 00000000..61a5e8f2 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue/shift_right_negative_lvalue_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment.sol new file mode 100644 index 00000000..00ac9662 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment.sol @@ -0,0 +1,19 @@ +contract C { + function f(int256 a, uint256 b) public returns (int256) { + a >>= b; + return a; + } +} +// ---- +// f(int256,uint256): -4266, 0 -> -4266 +// f(int256,uint256): -4266, 1 -> -2133 +// f(int256,uint256): -4266, 4 -> -267 +// f(int256,uint256): -4266, 8 -> -17 +// f(int256,uint256): -4266, 16 -> -1 +// f(int256,uint256): -4266, 17 -> -1 +// f(int256,uint256): -4267, 0 -> -4267 +// f(int256,uint256): -4267, 1 -> -2134 +// f(int256,uint256): -4267, 4 -> -267 +// f(int256,uint256): -4267, 8 -> -17 +// f(int256,uint256): -4267, 16 -> -1 +// f(int256,uint256): -4267, 17 -> -1 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment_standard_input.json new file mode 100644 index 00000000..fa46f211 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_assignment/shift_right_negative_lvalue_assignment_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16.sol new file mode 100644 index 00000000..50612a6f --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16.sol @@ -0,0 +1,18 @@ +contract C { + function f(int16 a, uint16 b) public returns (int256) { + return a >> b; + } +} +// ---- +// f(int16,uint16): -4266, 0 -> -4266 +// f(int16,uint16): -4266, 1 -> -2133 +// f(int16,uint16): -4266, 4 -> -267 +// f(int16,uint16): -4266, 8 -> -17 +// f(int16,uint16): -4266, 16 -> -1 +// f(int16,uint16): -4266, 17 -> -1 +// f(int16,uint16): -4267, 0 -> -4267 +// f(int16,uint16): -4267, 1 -> -2134 +// f(int16,uint16): -4267, 4 -> -267 +// f(int16,uint16): -4267, 8 -> -17 +// f(int16,uint16): -4267, 16 -> -1 +// f(int16,uint16): -4267, 17 -> -1 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16_standard_input.json new file mode 100644 index 00000000..9dc01329 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int16/shift_right_negative_lvalue_int16_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32.sol new file mode 100644 index 00000000..024eb325 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32.sol @@ -0,0 +1,18 @@ +contract C { + function f(int32 a, uint32 b) public returns (int256) { + return a >> b; + } +} +// ---- +// f(int32,uint32): -4266, 0 -> -4266 +// f(int32,uint32): -4266, 1 -> -2133 +// f(int32,uint32): -4266, 4 -> -267 +// f(int32,uint32): -4266, 8 -> -17 +// f(int32,uint32): -4266, 16 -> -1 +// f(int32,uint32): -4266, 17 -> -1 +// f(int32,uint32): -4267, 0 -> -4267 +// f(int32,uint32): -4267, 1 -> -2134 +// f(int32,uint32): -4267, 4 -> -267 +// f(int32,uint32): -4267, 8 -> -17 +// f(int32,uint32): -4267, 16 -> -1 +// f(int32,uint32): -4267, 17 -> -1 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32_standard_input.json new file mode 100644 index 00000000..e4c90fab --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int32/shift_right_negative_lvalue_int32_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8.sol new file mode 100644 index 00000000..9cff6c3b --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8.sol @@ -0,0 +1,18 @@ +contract C { + function f(int8 a, uint8 b) public returns (int256) { + return a >> b; + } +} +// ---- +// f(int8,uint8): -66, 0 -> -66 +// f(int8,uint8): -66, 1 -> -33 +// f(int8,uint8): -66, 4 -> -5 +// f(int8,uint8): -66, 8 -> -1 +// f(int8,uint8): -66, 16 -> -1 +// f(int8,uint8): -66, 17 -> -1 +// f(int8,uint8): -67, 0 -> -67 +// f(int8,uint8): -67, 1 -> -34 +// f(int8,uint8): -67, 4 -> -5 +// f(int8,uint8): -67, 8 -> -1 +// f(int8,uint8): -67, 16 -> -1 +// f(int8,uint8): -67, 17 -> -1 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8_standard_input.json new file mode 100644 index 00000000..bcc7938e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_int8/shift_right_negative_lvalue_int8_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1.sol new file mode 100644 index 00000000..0b8d0e83 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +contract C { + function f(int16 a, uint16 b) public returns (int16) { + return a >> b; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 +// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc +// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 +// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 +// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1_standard_input.json new file mode 100644 index 00000000..f6659080 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v1/shift_right_negative_lvalue_signextend_int16_v1_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2.sol new file mode 100644 index 00000000..f2c02448 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + + +contract C { + function f(int16 a, uint16 b) public returns (int16) { + return a >> b; + } +} +// ---- +// f(int16,uint16): 0xff99, 0x00 -> FAILURE +// f(int16,uint16): 0xff99, 0x01 -> FAILURE +// f(int16,uint16): 0xff99, 0x02 -> FAILURE +// f(int16,uint16): 0xff99, 0x04 -> FAILURE +// f(int16,uint16): 0xff99, 0x08 -> FAILURE diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2_standard_input.json new file mode 100644 index 00000000..4fa5a5e5 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int16_v2/shift_right_negative_lvalue_signextend_int16_v2_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1.sol new file mode 100644 index 00000000..a6b6378c --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +contract C { + function f(int32 a, uint32 b) public returns (int32) { + return a >> b; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 +// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc +// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 +// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 +// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1_standard_input.json new file mode 100644 index 00000000..de6a7da0 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v1/shift_right_negative_lvalue_signextend_int32_v1_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2.sol new file mode 100644 index 00000000..9c3090a7 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + + +contract C { + function f(int32 a, uint32 b) public returns (int32) { + return a >> b; + } +} +// ---- +// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2_standard_input.json new file mode 100644 index 00000000..d8e29e28 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int32_v2/shift_right_negative_lvalue_signextend_int32_v2_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1.sol new file mode 100644 index 00000000..52529a85 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +contract C { + function f(int8 a, uint8 b) public returns (int8) { + return a >> b; + } +} +// ==== +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 +// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc +// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 +// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 +// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1_standard_input.json new file mode 100644 index 00000000..54a14bec --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v1/shift_right_negative_lvalue_signextend_int8_v1_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + }, + "shift_constant_right.sol": { + "content": "contract C {\n uint256 public a = 0x4200 >> 8;\n}\n// ----\n// a() -> 0x42\n" + }, + "shift_right_negative_lvalue_signextend_int8_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2.sol b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2.sol new file mode 100644 index 00000000..8d3cec4e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; + + +contract C { + function f(int8 a, uint8 b) public returns (int8) { + return a >> b; + } +} +// ---- +// f(int8,uint8): 0x99, 0x00 -> FAILURE +// f(int8,uint8): 0x99, 0x01 -> FAILURE +// f(int8,uint8): 0x99, 0x02 -> FAILURE +// f(int8,uint8): 0x99, 0x04 -> FAILURE +// f(int8,uint8): 0x99, 0x08 -> FAILURE diff --git a/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2_standard_input.json new file mode 100644 index 00000000..4c2149c8 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_negative_lvalue_signextend_int8_v2/shift_right_negative_lvalue_signextend_int8_v2_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + }, + "shift_right_negative_lvalue_int8.sol": { + "content": "contract C {\n function f(int8 a, uint8 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): -66, 0 -> -66\n// f(int8,uint8): -66, 1 -> -33\n// f(int8,uint8): -66, 4 -> -5\n// f(int8,uint8): -66, 8 -> -1\n// f(int8,uint8): -66, 16 -> -1\n// f(int8,uint8): -66, 17 -> -1\n// f(int8,uint8): -67, 0 -> -67\n// f(int8,uint8): -67, 1 -> -34\n// f(int8,uint8): -67, 4 -> -5\n// f(int8,uint8): -67, 8 -> -1\n// f(int8,uint8): -67, 16 -> -1\n// f(int8,uint8): -67, 17 -> -1\n" + }, + "shift_right_negative_literal.sol": { + "content": "contract C {\n function f1() public pure returns (bool) {\n return (-4266 >> 0) == -4266;\n }\n\n function f2() public pure returns (bool) {\n return (-4266 >> 1) == -2133;\n }\n\n function f3() public pure returns (bool) {\n return (-4266 >> 4) == -267;\n }\n\n function f4() public pure returns (bool) {\n return (-4266 >> 8) == -17;\n }\n\n function f5() public pure returns (bool) {\n return (-4266 >> 16) == -1;\n }\n\n function f6() public pure returns (bool) {\n return (-4266 >> 17) == -1;\n }\n\n function g1() public pure returns (bool) {\n return (-4267 >> 0) == -4267;\n }\n\n function g2() public pure returns (bool) {\n return (-4267 >> 1) == -2134;\n }\n\n function g3() public pure returns (bool) {\n return (-4267 >> 4) == -267;\n }\n\n function g4() public pure returns (bool) {\n return (-4267 >> 8) == -17;\n }\n\n function g5() public pure returns (bool) {\n return (-4267 >> 16) == -1;\n }\n\n function g6() public pure returns (bool) {\n return (-4267 >> 17) == -1;\n }\n}\n// ----\n// f1() -> true\n// f2() -> true\n// f3() -> true\n// f4() -> true\n// f5() -> true\n// f6() -> true\n// g1() -> true\n// g2() -> true\n// g3() -> true\n// g4() -> true\n// g5() -> true\n// g6() -> true\n" + }, + "shift_left_larger_type.sol": { + "content": "// This basically tests proper cleanup and conversion. It should not convert x to int8.\ncontract C {\n function f() public returns (int8) {\n uint8 x = 254;\n int8 y = 1;\n return y << x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "shift_constant_right_assignment.sol": { + "content": "contract C {\n function f() public returns (uint256 a) {\n a = 0x4200;\n a >>= 8;\n }\n}\n// ----\n// f() -> 0x42\n" + }, + "shift_left_assignment.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n a <<= b;\n return a;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_right_negative_lvalue_signextend_int8_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int8 a, uint8 b) public returns (int8) {\n return a >> b;\n }\n}\n// ----\n// f(int8,uint8): 0x99, 0x00 -> FAILURE\n// f(int8,uint8): 0x99, 0x01 -> FAILURE\n// f(int8,uint8): 0x99, 0x02 -> FAILURE\n// f(int8,uint8): 0x99, 0x04 -> FAILURE\n// f(int8,uint8): 0x99, 0x08 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32.sol b/examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32.sol new file mode 100644 index 00000000..2619ea33 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32.sol @@ -0,0 +1,10 @@ +contract C { + function f(uint32 a, uint32 b) public returns (uint256) { + return a >> b; + } +} +// ---- +// f(uint32,uint32): 0x4266, 0x0 -> 0x4266 +// f(uint32,uint32): 0x4266, 0x8 -> 0x42 +// f(uint32,uint32): 0x4266, 0x10 -> 0 +// f(uint32,uint32): 0x4266, 0x11 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32_standard_input.json new file mode 100644 index 00000000..84dc20ec --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_uint32/shift_right_uint32_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8.sol b/examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8.sol new file mode 100644 index 00000000..1792d875 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint8 a, uint8 b) public returns (uint256) { + return a >> b; + } +} +// ---- +// f(uint8,uint8): 0x66, 0x0 -> 0x66 +// f(uint8,uint8): 0x66, 0x8 -> 0x0 diff --git a/examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8_standard_input.json new file mode 100644 index 00000000..7eefab74 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_right_uint8/shift_right_uint8_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue.sol b/examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue.sol new file mode 100644 index 00000000..6f4f95e9 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue.sol @@ -0,0 +1,12 @@ +contract C { + function f(int256 a, uint256 b) public returns (int256) { + return a << b; + } + + function g(int256 a, uint256 b) public returns (int256) { + return a >> b; + } +} +// ---- +// f(int256,uint256): 1, -1 -> 0 +// g(int256,uint256): 1, -1 -> 0 diff --git a/examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue_standard_input.json b/examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue_standard_input.json new file mode 100644 index 00000000..6df0ae37 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shift_underflow_negative_rvalue/shift_underflow_negative_rvalue_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + }, + "shift_right_negative_lvalue_int16.sol": { + "content": "contract C {\n function f(int16 a, uint16 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): -4266, 0 -> -4266\n// f(int16,uint16): -4266, 1 -> -2133\n// f(int16,uint16): -4266, 4 -> -267\n// f(int16,uint16): -4266, 8 -> -17\n// f(int16,uint16): -4266, 16 -> -1\n// f(int16,uint16): -4266, 17 -> -1\n// f(int16,uint16): -4267, 0 -> -4267\n// f(int16,uint16): -4267, 1 -> -2134\n// f(int16,uint16): -4267, 4 -> -267\n// f(int16,uint16): -4267, 8 -> -17\n// f(int16,uint16): -4267, 16 -> -1\n// f(int16,uint16): -4267, 17 -> -1\n" + }, + "shift_left.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x426600\n// f(uint256,uint256): 0x4266, 0x10 -> 0x42660000\n// f(uint256,uint256): 0x4266, 0x11 -> 0x84cc0000\n// f(uint256,uint256): 0x4266, 0xf0 -> 0x4266000000000000000000000000000000000000000000000000000000000000\n// f(uint256,uint256): 0x4266, 0x100 -> 0\n" + }, + "shift_overflow.sol": { + "content": "contract C {\n function leftU(uint8 x, uint8 y) public returns (uint8) {\n return x << y;\n }\n\n function leftS(int8 x, uint8 y) public returns (int8) {\n return x << y;\n }\n}\n// ----\n// leftU(uint8,uint8): 255, 8 -> 0\n// leftU(uint8,uint8): 255, 1 -> 254\n// leftU(uint8,uint8): 255, 0 -> 255\n// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. #\n// leftS(int8,uint8): 1, 6 -> 64\n" + }, + "shift_right_negative_lvalue_int32.sol": { + "content": "contract C {\n function f(int32 a, uint32 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): -4266, 0 -> -4266\n// f(int32,uint32): -4266, 1 -> -2133\n// f(int32,uint32): -4266, 4 -> -267\n// f(int32,uint32): -4266, 8 -> -17\n// f(int32,uint32): -4266, 16 -> -1\n// f(int32,uint32): -4266, 17 -> -1\n// f(int32,uint32): -4267, 0 -> -4267\n// f(int32,uint32): -4267, 1 -> -2134\n// f(int32,uint32): -4267, 4 -> -267\n// f(int32,uint32): -4267, 8 -> -17\n// f(int32,uint32): -4267, 16 -> -1\n// f(int32,uint32): -4267, 17 -> -1\n" + }, + "bitwise_shifting_constants_constantinople.sol": { + "content": "contract C {\n function shl_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(2, 1)\n }\n assert(c == 4);\n return true;\n }\n\n function shl_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n );\n return true;\n }\n\n function shl_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shl(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n\n function shr_1() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(1, 3)\n }\n assert(c == 1);\n return true;\n }\n\n function shr_2() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 1,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(\n c ==\n 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n );\n return true;\n }\n\n function shr_3() public returns (bool) {\n uint256 c;\n assembly {\n c := shr(\n 256,\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n )\n }\n assert(c == 0);\n return true;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_1() -> 0x01\n// shl_2() -> 0x01\n// shl_3() -> 0x01\n// shr_1() -> 0x01\n// shr_2() -> 0x01\n// shr_3() -> 0x01\n" + }, + "shift_underflow_negative_rvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a << b;\n }\n\n function g(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): 1, -1 -> 0\n// g(int256,uint256): 1, -1 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_shifts_shifts/shifts.sol b/examples/test/semanticTests/operators_shifts_shifts/shifts.sol new file mode 100644 index 00000000..e202f288 --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shifts/shifts.sol @@ -0,0 +1,9 @@ +contract C { + function f(uint x) public returns (uint y) { + assembly { y := shl(2, x) } + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// f(uint256): 7 -> 28 diff --git a/examples/test/semanticTests/operators_shifts_shifts/shifts_standard_input.json b/examples/test/semanticTests/operators_shifts_shifts/shifts_standard_input.json new file mode 100644 index 00000000..249d494e --- /dev/null +++ b/examples/test/semanticTests/operators_shifts_shifts/shifts_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "shift_right_garbled_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> FAILURE\n" + }, + "shift_left_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0\n" + }, + "shift_right_garbled_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n assembly {\n a := 0xffffffff\n }\n // Higher bits should be cleared before the shift\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8,uint8): 0x00, 0x04 -> 0x0f\n// f(uint8,uint8): 0x00, 0x1004 -> 0x0f\n" + }, + "shift_negative_constant_right.sol": { + "content": "contract C {\n int256 public a = -0x4200 >> 8;\n}\n// ----\n// a() -> -66\n" + }, + "bitwise_shifting_constantinople_combined.sol": { + "content": "contract C {\n function shl_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0, a)\n }\n }\n\n function shr_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0, a)\n }\n }\n\n function sar_zero(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0, a)\n }\n }\n\n function shl_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x110, a)\n }\n }\n\n function shr_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x110, a)\n }\n }\n\n function sar_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0x110, a)\n }\n }\n\n function shl_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(4, shl(12, a))\n }\n }\n\n function shr_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(4, shr(12, a))\n }\n }\n\n function sar_combined(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(4, sar(12, a))\n }\n }\n\n function shl_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0xd0, shl(0x40, a))\n }\n }\n\n function shl_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shl(0x01, shl(not(0x00), a))\n }\n }\n\n function shr_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0xd0, shr(0x40, a))\n }\n }\n\n function shr_combined_overflow(uint256 a) public returns (uint256 c) {\n assembly {\n c := shr(0x01, shr(not(0x00), a))\n }\n }\n\n function sar_combined_large(uint256 a) public returns (uint256 c) {\n assembly {\n c := sar(0xd0, sar(0x40, a))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl_zero(uint256): 0x00 -> 0x00\n// shl_zero(uint256): 0xffff -> 0xffff\n// shl_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr_zero(uint256): 0x00 -> 0x00\n// shr_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_zero(uint256): 0x00 -> 0x00\n// sar_zero(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_large(uint256): 0x00 -> 0x00\n// shl_large(uint256): 0xffff -> 0x00\n// shl_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_large(uint256): 0x00 -> 0x00\n// shr_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0x00 -> 0x00\n// sar_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined(uint256): 0x00 -> 0x00\n// shl_combined(uint256): 0xffff -> 0xffff0000\n// shl_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000\n// shr_combined(uint256): 0x00 -> 0x00\n// shr_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0x00 -> 0x00\n// sar_combined(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar_combined(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shl_combined_large(uint256): 0x00 -> 0x00\n// shl_combined_large(uint256): 0xffff -> 0x00\n// shl_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shl_combined_overflow(uint256): 0x02 -> 0x00\n// shr_combined_large(uint256): 0x00 -> 0x00\n// shr_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// shr_combined_overflow(uint256): 0x02 -> 0x00\n// sar_combined_large(uint256): 0x00 -> 0x00\n// sar_combined_large(uint256): 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00\n// sar_combined_large(uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_bytes_cleanup_viaYul.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_left_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a << b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x426600\n// f(uint32,uint32): 0x4266, 0x10 -> 0x42660000\n// f(uint32,uint32): 0x4266, 0x11 -> 0x84cc0000\n// f(uint32,uint32): 0x4266, 0x20 -> 0\n" + }, + "bitwise_shifting_constantinople.sol": { + "content": "contract C {\n function shl(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shl(b, a)\n }\n }\n\n function shr(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := shr(b, a)\n }\n }\n\n function sar(uint256 a, uint256 b) public returns (uint256 c) {\n assembly {\n c := sar(b, a)\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// shl(uint256,uint256): 0x01, 0x02 -> 0x04\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n// shl(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// shr(uint256,uint256): 0x03, 0x01 -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0x01\n// shr(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0x00\n// sar(uint256,uint256): 0x03, 0x01 -> 0x01\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n// sar(uint256,uint256): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x100 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right.sol": { + "content": "contract C {\n function f(uint256 a, uint256 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint256,uint256): 0x4266, 0x0 -> 0x4266\n// f(uint256,uint256): 0x4266, 0x8 -> 0x42\n// f(uint256,uint256): 0x4266, 0x10 -> 0\n// f(uint256,uint256): 0x4266, 0x11 -> 0\n// f(uint256,uint256): 57896044618658097711785492504343953926634992332820282019728792003956564819968, 5 -> 1809251394333065553493296640760748560207343510400633813116524750123642650624\n" + }, + "shift_bytes_cleanup.sol": { + "content": "contract C {\n\tfunction l(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\t// When compiling via IR, `x` is truncated before applying\n\t\t// the operation.\n\t\treturn x << y;\n\t}\n\tfunction r(uint8 y) public returns (bytes20) {\n\t\tbytes20 x;\n\t\tassembly { x := \"12345678901234567890abcde\" }\n\t\treturn x >> y;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// l(uint8): 64 -> 0x3930313233343536373839300000000000000000000000000000000000000000\n// r(uint8): 64 -> 0x313233343536373839303132000000000000000000000000\n" + }, + "shift_constant_left.sol": { + "content": "contract C {\n uint256 public a = 0x42 << 8;\n}\n// ----\n// a() -> 0x4200\n" + }, + "shift_cleanup.sol": { + "content": "contract C {\n function f() public returns (uint16 x) {\n unchecked {\n x = 0xffff;\n x += 32;\n x <<= 8;\n x >>= 16;\n }\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_right_negative_lvalue_signextend_int32_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE\n// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int16_v2.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> FAILURE\n// f(int16,uint16): 0xff99, 0x01 -> FAILURE\n// f(int16,uint16): 0xff99, 0x02 -> FAILURE\n// f(int16,uint16): 0xff99, 0x04 -> FAILURE\n// f(int16,uint16): 0xff99, 0x08 -> FAILURE\n" + }, + "shift_right_negative_lvalue_signextend_int32_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int32 a, uint32 b) public returns (int32) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_uint32.sol": { + "content": "contract C {\n function f(uint32 a, uint32 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint32,uint32): 0x4266, 0x0 -> 0x4266\n// f(uint32,uint32): 0x4266, 0x8 -> 0x42\n// f(uint32,uint32): 0x4266, 0x10 -> 0\n// f(uint32,uint32): 0x4266, 0x11 -> 0\n" + }, + "shift_cleanup_garbled.sol": { + "content": "contract C {\n function f() public returns (uint8 x) {\n assembly {\n x := 0xffff\n }\n x >>= 8;\n }\n}\n// ----\n// f() -> 0x0\n" + }, + "shift_negative_constant_left.sol": { + "content": "contract C {\n int256 public a = -0x42 << 8;\n}\n// ----\n// a() -> -16896\n" + }, + "shift_right_negative_lvalue_signextend_int16_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function f(int16 a, uint16 b) public returns (int16) {\n return a >> b;\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99\n// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc\n// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6\n// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9\n// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n" + }, + "shift_right_negative_lvalue.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n return a >> b;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shift_right_uint8.sol": { + "content": "contract C {\n function f(uint8 a, uint8 b) public returns (uint256) {\n return a >> b;\n }\n}\n// ----\n// f(uint8,uint8): 0x66, 0x0 -> 0x66\n// f(uint8,uint8): 0x66, 0x8 -> 0x0\n" + }, + "shift_right_negative_lvalue_assignment.sol": { + "content": "contract C {\n function f(int256 a, uint256 b) public returns (int256) {\n a >>= b;\n return a;\n }\n}\n// ----\n// f(int256,uint256): -4266, 0 -> -4266\n// f(int256,uint256): -4266, 1 -> -2133\n// f(int256,uint256): -4266, 4 -> -267\n// f(int256,uint256): -4266, 8 -> -17\n// f(int256,uint256): -4266, 16 -> -1\n// f(int256,uint256): -4266, 17 -> -1\n// f(int256,uint256): -4267, 0 -> -4267\n// f(int256,uint256): -4267, 1 -> -2134\n// f(int256,uint256): -4267, 4 -> -267\n// f(int256,uint256): -4267, 8 -> -17\n// f(int256,uint256): -4267, 16 -> -1\n// f(int256,uint256): -4267, 17 -> -1\n" + }, + "shifts.sol": { + "content": "contract C {\n function f(uint x) public returns (uint y) {\n assembly { y := shl(2, x) }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(uint256): 7 -> 28\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement.sol b/examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement.sol new file mode 100644 index 00000000..88915301 --- /dev/null +++ b/examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement.sol @@ -0,0 +1,15 @@ +contract C { + int transient x; + function f() public returns (int) { + ++x; + ++x; + --x; + x++; + x--; + return x; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement_standard_input.json b/examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement_standard_input.json new file mode 100644 index 00000000..c9b8fdf8 --- /dev/null +++ b/examples/test/semanticTests/operators_transient_storage_variable_increment_decrement/transient_storage_variable_increment_decrement_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "compound_assign_transient_storage.sol": { + "content": "contract test {\n\tuint value1;\n\tuint transient value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 += value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 11\n// f(uint256,uint256): 2, 25 -> 0x3c\n// f(uint256,uint256): 3, 69 -> 0xdc\n// f(uint256,uint256): 4, 84 -> 353\n// f(uint256,uint256): 5, 2 -> 0x20\n// f(uint256,uint256): 6, 51 -> 334\n// f(uint256,uint256): 7, 48 -> 371\n" + }, + "compound_assign.sol": { + "content": "contract test {\n\tuint value1;\n\tuint value2;\n\tfunction f(uint x, uint y) public returns (uint w) {\n\t\tuint value3 = y;\n\t\tvalue1 += x;\n\t\tvalue3 *= x;\n\t\tvalue2 *= value3 + value1;\n\t\treturn value2 += 7;\n\t}\n}\n// ----\n// f(uint256,uint256): 0, 6 -> 7\n// f(uint256,uint256): 1, 3 -> 0x23\n// f(uint256,uint256): 2, 25 -> 0x0746\n// f(uint256,uint256): 3, 69 -> 396613\n// f(uint256,uint256): 4, 84 -> 137228105\n// f(uint256,uint256): 5, 2 -> 0xcc7c5e28\n// f(uint256,uint256): 6, 51 -> 1121839760671\n// f(uint256,uint256): 7, 48 -> 408349672884251\n" + }, + "transient_storage_variable_increment_decrement.sol": { + "content": "contract C {\n int transient x;\n function f() public returns (int) {\n ++x;\n ++x;\n --x;\n x++;\n x--;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators.sol b/examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators.sol new file mode 100644 index 00000000..315356b6 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators.sol @@ -0,0 +1,92 @@ +type Int is int8; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as %, + eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >= +} for Int global; + +function bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); } +function bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); } +function bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); } +function bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); } + +function add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); } +function sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); } +function unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); } +function mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); } +function div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); } +function mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); } + +function eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); } +function noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); } +function lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); } +function gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); } +function leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); } +function geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); } + +contract C { + Int constant ZERO = Int.wrap(0); + Int constant ONE = Int.wrap(1); + Int constant TWO = Int.wrap(2); + Int constant THREE = Int.wrap(3); + Int constant SIX = Int.wrap(6); + + function testBitwise() public pure { + assert(Int.unwrap(ONE | TWO) == 3); + assert(Int.unwrap(ONE | ZERO) == 1); + + assert(Int.unwrap(ONE & THREE) == 1); + assert(Int.unwrap(ONE & ONE) == 1); + + assert(Int.unwrap(TWO ^ TWO) == 0); + assert(Int.unwrap(TWO ^ ONE) == 3); + + assert(Int.unwrap(~ZERO) == -1); + assert(Int.unwrap(~ONE) == -2); + assert(Int.unwrap(~TWO) == -3); + } + + function testArithmetic() public pure { + assert(Int.unwrap(ONE + TWO) == 3); + assert(Int.unwrap(ONE + ZERO) == 1); + + assert(Int.unwrap(TWO - ONE) == 1); + assert(Int.unwrap(THREE - THREE) == 0); + + assert(Int.unwrap(-TWO) == -2); + assert(Int.unwrap(-ZERO) == 0); + + assert(Int.unwrap(ONE * ONE) == 1); + assert(Int.unwrap(THREE * TWO) == 6); + + assert(Int.unwrap(SIX / TWO) == 3); + assert(Int.unwrap(THREE / TWO) == 1); + + assert(Int.unwrap(SIX % TWO) == 0); + assert(Int.unwrap(THREE % TWO) == 1); + } + + function testComparison() public pure { + assert((ONE == ONE) == true); + assert((ONE == TWO) == false); + + assert((ONE != ONE) == false); + assert((ONE != TWO) == true); + + assert((ONE < TWO) == true); + assert((TWO < ONE) == false); + + assert((ONE <= TWO) == true); + assert((TWO <= ONE) == false); + + assert((ONE > TWO) == false); + assert((TWO > ONE) == true); + + assert((ONE >= TWO) == false); + assert((TWO >= ONE) == true); + } +} +// ---- +// testBitwise() -> +// testArithmetic() -> +// testComparison() -> diff --git a/examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators_standard_input.json b/examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators_standard_input.json new file mode 100644 index 00000000..0a23cbbf --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_all_possible_operators/all_possible_operators_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators.sol b/examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators.sol new file mode 100644 index 00000000..868a5396 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators.sol @@ -0,0 +1,670 @@ +type Int8 is int8; +type Int16 is int16; +type Int24 is int24; +type Int32 is int32; +type Int40 is int40; +type Int48 is int48; +type Int56 is int56; +type Int64 is int64; +type Int72 is int72; +type Int80 is int80; +type Int88 is int88; +type Int96 is int96; +type Int104 is int104; +type Int112 is int112; +type Int120 is int120; +type Int128 is int128; +type Int136 is int136; +type Int144 is int144; +type Int152 is int152; +type Int160 is int160; +type Int168 is int168; +type Int176 is int176; +type Int184 is int184; +type Int192 is int192; +type Int200 is int200; +type Int208 is int208; +type Int216 is int216; +type Int224 is int224; +type Int232 is int232; +type Int240 is int240; +type Int248 is int248; +type Int256 is int256; +type Int is int; + +type Uint8 is uint8; +type Uint16 is uint16; +type Uint24 is uint24; +type Uint32 is uint32; +type Uint40 is uint40; +type Uint48 is uint48; +type Uint56 is uint56; +type Uint64 is uint64; +type Uint72 is uint72; +type Uint80 is uint80; +type Uint88 is uint88; +type Uint96 is uint96; +type Uint104 is uint104; +type Uint112 is uint112; +type Uint120 is uint120; +type Uint128 is uint128; +type Uint136 is uint136; +type Uint144 is uint144; +type Uint152 is uint152; +type Uint160 is uint160; +type Uint168 is uint168; +type Uint176 is uint176; +type Uint184 is uint184; +type Uint192 is uint192; +type Uint200 is uint200; +type Uint208 is uint208; +type Uint216 is uint216; +type Uint224 is uint224; +type Uint232 is uint232; +type Uint240 is uint240; +type Uint248 is uint248; +type Uint256 is uint256; +type Uint is uint; + +type Bytes1 is bytes1; +type Bytes2 is bytes2; +type Bytes3 is bytes3; +type Bytes4 is bytes4; +type Bytes5 is bytes5; +type Bytes6 is bytes6; +type Bytes7 is bytes7; +type Bytes8 is bytes8; +type Bytes9 is bytes9; +type Bytes10 is bytes10; +type Bytes11 is bytes11; +type Bytes12 is bytes12; +type Bytes13 is bytes13; +type Bytes14 is bytes14; +type Bytes15 is bytes15; +type Bytes16 is bytes16; +type Bytes17 is bytes17; +type Bytes18 is bytes18; +type Bytes19 is bytes19; +type Bytes20 is bytes20; +type Bytes21 is bytes21; +type Bytes22 is bytes22; +type Bytes23 is bytes23; +type Bytes24 is bytes24; +type Bytes25 is bytes25; +type Bytes26 is bytes26; +type Bytes27 is bytes27; +type Bytes28 is bytes28; +type Bytes29 is bytes29; +type Bytes30 is bytes30; +type Bytes31 is bytes31; +type Bytes32 is bytes32; + +type Address is address; +type AddressPayable is address payable; + +type Bool is bool; + +using {bitorInt8 as |, unsubInt8 as -} for Int8 global; +using {bitorInt16 as |, unsubInt16 as -} for Int16 global; +using {bitorInt24 as |, unsubInt24 as -} for Int24 global; +using {bitorInt32 as |, unsubInt32 as -} for Int32 global; +using {bitorInt40 as |, unsubInt40 as -} for Int40 global; +using {bitorInt48 as |, unsubInt48 as -} for Int48 global; +using {bitorInt56 as |, unsubInt56 as -} for Int56 global; +using {bitorInt64 as |, unsubInt64 as -} for Int64 global; +using {bitorInt72 as |, unsubInt72 as -} for Int72 global; +using {bitorInt80 as |, unsubInt80 as -} for Int80 global; +using {bitorInt88 as |, unsubInt88 as -} for Int88 global; +using {bitorInt96 as |, unsubInt96 as -} for Int96 global; +using {bitorInt104 as |, unsubInt104 as -} for Int104 global; +using {bitorInt112 as |, unsubInt112 as -} for Int112 global; +using {bitorInt120 as |, unsubInt120 as -} for Int120 global; +using {bitorInt128 as |, unsubInt128 as -} for Int128 global; +using {bitorInt136 as |, unsubInt136 as -} for Int136 global; +using {bitorInt144 as |, unsubInt144 as -} for Int144 global; +using {bitorInt152 as |, unsubInt152 as -} for Int152 global; +using {bitorInt160 as |, unsubInt160 as -} for Int160 global; +using {bitorInt168 as |, unsubInt168 as -} for Int168 global; +using {bitorInt176 as |, unsubInt176 as -} for Int176 global; +using {bitorInt184 as |, unsubInt184 as -} for Int184 global; +using {bitorInt192 as |, unsubInt192 as -} for Int192 global; +using {bitorInt200 as |, unsubInt200 as -} for Int200 global; +using {bitorInt208 as |, unsubInt208 as -} for Int208 global; +using {bitorInt216 as |, unsubInt216 as -} for Int216 global; +using {bitorInt224 as |, unsubInt224 as -} for Int224 global; +using {bitorInt232 as |, unsubInt232 as -} for Int232 global; +using {bitorInt240 as |, unsubInt240 as -} for Int240 global; +using {bitorInt248 as |, unsubInt248 as -} for Int248 global; +using {bitorInt256 as |, unsubInt256 as -} for Int256 global; +using {bitorInt as |, unsubInt as -} for Int global; + +using {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global; +using {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global; +using {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global; +using {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global; +using {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global; +using {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global; +using {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global; +using {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global; +using {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global; +using {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global; +using {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global; +using {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global; +using {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global; +using {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global; +using {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global; +using {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global; +using {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global; +using {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global; +using {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global; +using {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global; +using {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global; +using {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global; +using {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global; +using {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global; +using {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global; +using {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global; +using {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global; +using {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global; +using {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global; +using {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global; +using {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global; +using {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global; +using {bitorUint as |, bitnotUint as ~} for Uint global; + +using {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global; +using {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global; +using {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global; +using {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global; +using {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global; +using {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global; +using {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global; +using {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global; +using {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global; +using {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global; +using {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global; +using {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global; +using {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global; +using {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global; +using {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global; +using {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global; +using {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global; +using {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global; +using {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global; +using {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global; +using {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global; +using {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global; +using {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global; +using {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global; +using {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global; +using {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global; +using {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global; +using {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global; +using {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global; +using {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global; +using {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global; +using {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global; + +function bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); } +function bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); } +function bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); } +function bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); } +function bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); } +function bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); } +function bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); } +function bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); } +function bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); } +function bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); } +function bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); } +function bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); } +function bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); } +function bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); } +function bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); } +function bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); } +function bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); } +function bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); } +function bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); } +function bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); } +function bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); } +function bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); } +function bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); } +function bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); } +function bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); } +function bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); } +function bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); } +function bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); } +function bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); } +function bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); } +function bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); } +function bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); } +function bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); } + +function unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); } +function unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); } +function unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); } +function unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); } +function unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); } +function unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); } +function unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); } +function unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); } +function unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); } +function unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); } +function unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); } +function unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); } +function unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); } +function unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); } +function unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); } +function unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); } +function unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); } +function unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); } +function unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); } +function unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); } +function unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); } +function unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); } +function unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); } +function unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); } +function unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); } +function unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); } +function unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); } +function unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); } +function unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); } +function unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); } +function unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); } +function unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); } +function unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); } + +function bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); } +function bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); } +function bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); } +function bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); } +function bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); } +function bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); } +function bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); } +function bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); } +function bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); } +function bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); } +function bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); } +function bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); } +function bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); } +function bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); } +function bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); } +function bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); } +function bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); } +function bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); } +function bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); } +function bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); } +function bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); } +function bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); } +function bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); } +function bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); } +function bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); } +function bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); } +function bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); } +function bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); } +function bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); } +function bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); } +function bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); } +function bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); } +function bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); } + +function bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); } +function bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); } +function bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); } +function bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); } +function bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); } +function bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); } +function bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); } +function bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); } +function bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); } +function bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); } +function bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); } +function bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); } +function bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); } +function bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); } +function bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); } +function bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); } +function bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); } +function bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); } +function bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); } +function bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); } +function bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); } +function bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); } +function bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); } +function bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); } +function bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); } +function bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); } +function bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); } +function bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); } +function bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); } +function bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); } +function bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); } +function bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); } +function bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); } + +function bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); } +function bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); } +function bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); } +function bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); } +function bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); } +function bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); } +function bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); } +function bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); } +function bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); } +function bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); } +function bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); } +function bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); } +function bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); } +function bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); } +function bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); } +function bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); } +function bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); } +function bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); } +function bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); } +function bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); } +function bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); } +function bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); } +function bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); } +function bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); } +function bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); } +function bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); } +function bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); } +function bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); } +function bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); } +function bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); } +function bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); } +function bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); } + +function bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); } +function bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); } +function bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); } +function bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); } +function bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); } +function bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); } +function bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); } +function bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); } +function bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); } +function bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); } +function bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); } +function bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); } +function bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); } +function bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); } +function bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); } +function bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); } +function bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); } +function bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); } +function bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); } +function bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); } +function bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); } +function bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); } +function bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); } +function bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); } +function bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); } +function bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); } +function bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); } +function bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); } +function bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); } +function bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); } +function bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); } +function bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); } + +using {bitorAddress as |, bitnotAddress as ~} for Address global; +using {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global; +using {bitorBool as |, bitnotBool as ~} for Bool global; + +function bitorAddress(Address x, Address y) pure returns (Address) { + return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y)))); +} +function bitnotAddress(Address x) pure returns (Address) { + return Address.wrap(address(~bytes20(Address.unwrap(x)))); +} + +function bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) { + return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y)))))); +} +function bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) { + return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x)))))); +} + +function bitorBool(Bool x, Bool y) pure returns (Bool) { + return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y)); +} +function bitnotBool(Bool x) pure returns (Bool) { + return Bool.wrap(!Bool.unwrap(x)); +} + +contract C { + function testIntBinary() public pure { + assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3); + assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3); + assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3); + assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3); + assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3); + assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3); + assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3); + assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3); + assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3); + assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3); + assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3); + assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3); + assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3); + assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3); + assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3); + assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3); + assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3); + assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3); + assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3); + assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3); + assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3); + assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3); + assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3); + assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3); + assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3); + assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3); + assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3); + assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3); + assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3); + assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3); + assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3); + assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3); + assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3); + } + + function testIntUnary() public pure { + assert(Int8.unwrap(-Int8.wrap(1)) == -1); + assert(Int16.unwrap(-Int16.wrap(1)) == -1); + assert(Int24.unwrap(-Int24.wrap(1)) == -1); + assert(Int32.unwrap(-Int32.wrap(1)) == -1); + assert(Int40.unwrap(-Int40.wrap(1)) == -1); + assert(Int48.unwrap(-Int48.wrap(1)) == -1); + assert(Int56.unwrap(-Int56.wrap(1)) == -1); + assert(Int64.unwrap(-Int64.wrap(1)) == -1); + assert(Int72.unwrap(-Int72.wrap(1)) == -1); + assert(Int80.unwrap(-Int80.wrap(1)) == -1); + assert(Int88.unwrap(-Int88.wrap(1)) == -1); + assert(Int96.unwrap(-Int96.wrap(1)) == -1); + assert(Int104.unwrap(-Int104.wrap(1)) == -1); + assert(Int112.unwrap(-Int112.wrap(1)) == -1); + assert(Int120.unwrap(-Int120.wrap(1)) == -1); + assert(Int128.unwrap(-Int128.wrap(1)) == -1); + assert(Int136.unwrap(-Int136.wrap(1)) == -1); + assert(Int144.unwrap(-Int144.wrap(1)) == -1); + assert(Int152.unwrap(-Int152.wrap(1)) == -1); + assert(Int160.unwrap(-Int160.wrap(1)) == -1); + assert(Int168.unwrap(-Int168.wrap(1)) == -1); + assert(Int176.unwrap(-Int176.wrap(1)) == -1); + assert(Int184.unwrap(-Int184.wrap(1)) == -1); + assert(Int192.unwrap(-Int192.wrap(1)) == -1); + assert(Int200.unwrap(-Int200.wrap(1)) == -1); + assert(Int208.unwrap(-Int208.wrap(1)) == -1); + assert(Int216.unwrap(-Int216.wrap(1)) == -1); + assert(Int224.unwrap(-Int224.wrap(1)) == -1); + assert(Int232.unwrap(-Int232.wrap(1)) == -1); + assert(Int240.unwrap(-Int240.wrap(1)) == -1); + assert(Int248.unwrap(-Int248.wrap(1)) == -1); + assert(Int256.unwrap(-Int256.wrap(1)) == -1); + assert(Int.unwrap(-Int.wrap(1)) == -1); + } + + function testUintBinary() public pure { + assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3); + assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3); + assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3); + assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3); + assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3); + assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3); + assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3); + assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3); + assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3); + assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3); + assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3); + assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3); + assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3); + assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3); + assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3); + assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3); + assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3); + assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3); + assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3); + assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3); + assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3); + assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3); + assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3); + assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3); + assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3); + assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3); + assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3); + assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3); + assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3); + assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3); + assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3); + assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3); + assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3); + } + + function testUintUnary() public pure { + assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1)); + assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1)); + assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1)); + assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1)); + assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1)); + assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1)); + assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1)); + assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1)); + assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1)); + assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1)); + assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1)); + assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1)); + assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1)); + assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1)); + assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1)); + assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1)); + assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1)); + assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1)); + assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1)); + assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1)); + assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1)); + assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1)); + assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1)); + assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1)); + assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1)); + assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1)); + assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1)); + assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1)); + assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1)); + assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1)); + assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1)); + assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1)); + assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1)); + } + + function testBytesBinary() public pure { + assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03)); + assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03))); + assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03))); + assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03))); + assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03))); + assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03))); + assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03))); + assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03))); + assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03))); + assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03))); + assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03))); + assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03))); + assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03))); + assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03))); + assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03))); + assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03))); + assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03))); + assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03))); + assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03))); + assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03))); + assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03))); + assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03))); + assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03))); + assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03))); + assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03))); + assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03))); + assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03))); + assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03))); + assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03))); + assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03))); + assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03))); + assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03))); + } + + function testBytesUnary() public pure { + assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01)); + assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01))); + assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01))); + assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01))); + assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01))); + assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01))); + assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01))); + assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01))); + assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01))); + assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01))); + assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01))); + assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01))); + assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01))); + assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01))); + assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01))); + assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01))); + assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01))); + assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01))); + assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01))); + assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01))); + assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01))); + assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01))); + assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01))); + assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01))); + assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01))); + assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01))); + assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01))); + assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01))); + assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01))); + assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01))); + assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01))); + assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01))); + } + + function testOtherBinary() public pure { + assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03)); + assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03))); + assert(Bool.unwrap(~Bool.wrap(true)) == false); + } + + function testOtherUnary() public pure { + assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0))); + assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0)))); + assert(Bool.unwrap(~Bool.wrap(true)) == false); + } +} +// ---- +// testIntBinary() -> +// testIntUnary() -> +// testUintBinary() -> +// testUintUnary() -> +// testBytesBinary() -> +// testBytesUnary() -> +// testOtherBinary() -> +// testOtherUnary() -> diff --git a/examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators_standard_input.json b/examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators_standard_input.json new file mode 100644 index 00000000..2d59d05b --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_all_possible_user_defined_value_types_with_operators/all_possible_user_defined_value_types_with_operators_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function.sol b/examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function.sol new file mode 100644 index 00000000..6f032386 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function.sol @@ -0,0 +1,20 @@ +type Int is int16; + +using {add as +, add} for Int global; + +function add(Int _a, Int _b) pure returns (Int) { + return Int.wrap(Int.unwrap(_a) + Int.unwrap(_b)); +} + +contract C { + function f() pure public returns (Int) { + return Int.wrap(5) + Int.wrap(5); + } + + function g() pure public returns (Int) { + return Int.wrap(7).add(Int.wrap(6)); + } +} +// ---- +// f() -> 10 +// g() -> 13 diff --git a/examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function_standard_input.json b/examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function_standard_input.json new file mode 100644 index 00000000..36e3e71e --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_attaching_and_defining_operator_with_same_function/attaching_and_defining_operator_with_same_function_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + }, + "operator_evaluation_order.sol": { + "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n event Wrapped(uint);\n event Probe(Bool);\n\n function toBool(uint x) public returns (Bool) {\n emit Wrapped(x);\n return Bool.wrap(x > 0);\n }\n\n function probe(Bool x) public returns (Bool) {\n emit Probe(x);\n return x;\n }\n\n function testSingleOperator() public {\n toBool(0) +\n (toBool(1) + toBool(2)) +\n toBool(3);\n }\n\n function testTwoBinaryOperators() public {\n toBool(0) * toBool(1) +\n (toBool(2) * toBool(3)) +\n toBool(4) * toBool(5);\n }\n\n function testBinaryAndUnaryOperators() public {\n -toBool(0) * -toBool(1) +\n (-toBool(2) * -toBool(3)) +\n -toBool(4) * -toBool(5);\n }\n\n function testOperatorsNestedInCalls() public {\n -probe(toBool(0) * -toBool(1)) +\n (-probe(toBool(2) * -toBool(3))) +\n -probe(toBool(4) * -toBool(5));\n }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n" + }, + "recursive_operator.sol": { + "content": "type Uint is uint;\nusing {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global;\n\nfunction unaryCountdown(Uint x) pure returns (Uint) {\n if (x == Uint.wrap(0))\n return Uint.wrap(0);\n\n return ~Uint.wrap(Uint.unwrap(x) - 1);\n}\n\nfunction binaryCountdown(Uint x, Uint y) pure returns (Uint) {\n if (x == Uint.wrap(0) && y == Uint.wrap(0))\n return Uint.wrap(0);\n if (x == Uint.wrap(0))\n return y ^ x;\n\n return Uint.wrap(Uint.unwrap(x) - 1) ^ y;\n}\n\nfunction eq(Uint x, Uint y) pure returns (bool) {\n return Uint.unwrap(x) == Uint.unwrap(y);\n}\n\ncontract C {\n function testUnary(Uint x) public pure returns (Uint) {\n return ~x;\n }\n\n function testBinary(Uint x, Uint y) public pure returns (Uint) {\n return x ^ y;\n }\n}\n// ----\n// testUnary(uint256): 0 -> 0\n// testUnary(uint256): 1 -> 0\n// testUnary(uint256): 99999999999 -> FAILURE\n// testBinary(uint256,uint256): 0, 0 -> 0\n// testBinary(uint256,uint256): 1, 0 -> 0\n// testBinary(uint256,uint256): 0, 1 -> 0\n// testBinary(uint256,uint256): 1, 1 -> 0\n// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE\n" + }, + "operator_parameter_and_return_cleanup_between_calls.sol": { + "content": "type U8 is uint8;\nusing {yoloAdd as +, yoloDiv as /} for U8 global;\n\nfunction yoloAdd(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := add(x, y) // Wrong! No cleanup.\n }\n}\n\nfunction yoloDiv(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := div(x, y) // Wrong! No cleanup.\n }\n}\n\ncontract C {\n function divAddNoOverflow(U8 a, U8 b, U8 c) external pure returns (U8) {\n return a / (b + c);\n }\n}\n// ----\n// divAddNoOverflow(uint8,uint8,uint8): 4, 0xff, 3 -> 0\n" + }, + "operator_precendence.sol": { + "content": "type Int is int64;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\ncontract C {\n Int constant I0 = Int.wrap(0);\n Int constant I1 = Int.wrap(1);\n Int constant I2 = Int.wrap(2);\n Int constant I3 = Int.wrap(3);\n Int constant I4 = Int.wrap(4);\n Int constant I5 = Int.wrap(5);\n Int constant I6 = Int.wrap(6);\n Int constant I7 = Int.wrap(7);\n Int constant I8 = Int.wrap(8);\n Int constant I10 = Int.wrap(10);\n Int constant I13 = Int.wrap(13);\n Int constant I15 = Int.wrap(15);\n Int constant I20 = Int.wrap(20);\n Int constant I128 = Int.wrap(128);\n\n function testBitwise() public pure {\n assert(Int.unwrap(I0 & I0 | I1) == (0 & 0 | 1));\n assert(Int.unwrap(I0 & I0 | I1) == ((0 & 0) | 1));\n }\n\n function testBitwise_arithmetic() public pure {\n assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (2 + 2 & ~1 | 6 * 6 - 4 & ~3));\n assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (((2 + 2) & (~1)) | (((6 * 6) - 4) & (~3))));\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == (1 + 8 / 4 - 5 % 6 * 7));\n assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == ((1 + (8 / 4)) - ((5 % 6) * 7)));\n }\n\n function testAll() public pure {\n assert(\n Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n (128 + 1 - 10 + 4 & ~1 ^ ~1 * 2 | -15 % -10 * 20 / 2 + 13 & ~3)\n );\n assert(\n Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n (\n (\n ((((128 + 1) - 10) + 4) & (~1)) ^\n ((~1) * 2)\n ) |\n ((((((-15) % (-10)) * 20) / 2) + 13) & (~3))\n )\n );\n }\n}\n// ----\n// testBitwise() ->\n// testBitwise_arithmetic() ->\n// testArithmetic() ->\n// testAll() ->\n" + }, + "attaching_and_defining_operator_with_same_function.sol": { + "content": "type Int is int16;\n\nusing {add as +, add} for Int global;\n\nfunction add(Int _a, Int _b) pure returns (Int) {\n return Int.wrap(Int.unwrap(_a) + Int.unwrap(_b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(5) + Int.wrap(5);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(7).add(Int.wrap(6));\n }\n}\n// ----\n// f() -> 10\n// g() -> 13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators.sol b/examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators.sol new file mode 100644 index 00000000..599e894b --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators.sol @@ -0,0 +1,22 @@ +type U8 is uint8; + +function checkedAdd(U8 x, U8 y) pure returns (U8) { + return U8.wrap(U8.unwrap(x) + U8.unwrap(y)); +} + +using {checkedAdd as +} for U8 global; + +contract C { + function testCheckedOperator() public pure returns (U8) { + return U8.wrap(250) + U8.wrap(10); + } + + function testCheckedOperatorInUncheckedBlock() public pure returns (U8) { + unchecked { + return U8.wrap(250) + U8.wrap(10); + } + } +} +// ---- +// testCheckedOperator() -> FAILURE, hex"4e487b71", 0x11 +// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators_standard_input.json b/examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators_standard_input.json new file mode 100644 index 00000000..e0b3981d --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_checked_operators/checked_operators_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations.sol b/examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations.sol new file mode 100644 index 00000000..ef36294a --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations.sol @@ -0,0 +1,18 @@ +type A is address; + +using {add as +} for A global; + +function add(A a, A b) pure returns (A) { + return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b)))); +} + +contract C { + function g() public pure returns (A) { + A a = A.wrap(0x3333333333333333333333333333333333333333); + A b = A.wrap(0x1111111111111111111111111111111111111111); + A c = A.wrap(0x5555555555555555555555555555555555555555); + return a + b + c; + } +} +// ---- +// g() -> 0x9999999999999999999999999999999999999999 diff --git a/examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations_standard_input.json b/examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations_standard_input.json new file mode 100644 index 00000000..b89c695d --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_consecutive_operator_invocations/consecutive_operator_invocations_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators.sol b/examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators.sol new file mode 100644 index 00000000..6f17b16e --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators.sol @@ -0,0 +1,22 @@ +type Fixed is int128; +using {add as +, mul as *} for Fixed global; + +int constant MULTIPLIER = 10**18; + +function add(Fixed a, Fixed b) pure returns (Fixed) { + return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b)); +} + +function mul(Fixed a, Fixed b) pure returns (Fixed) { + int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER; + if (int128(intermediate) != intermediate) { revert("Overflow"); } + return Fixed.wrap(int128(intermediate)); +} + +contract C { + function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) { + return value + value * percentage; + } +} +// ---- +// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000 diff --git a/examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators_standard_input.json b/examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators_standard_input.json new file mode 100644 index 00000000..5d707fca --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_fixed_point_udvt_with_operators/fixed_point_udvt_with_operators_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives.sol b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives.sol new file mode 100644 index 00000000..0b2d740a --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives.sol @@ -0,0 +1,26 @@ +type SmallInt is int; +type BigInt is int; + +using {addSmall as +} for SmallInt global; +using {addBig as +} for BigInt global; + +function addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) { + return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b)); +} + +function addBig(BigInt a, BigInt b) pure returns (BigInt) { + return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b))); +} + +contract C { + function small() public pure returns (SmallInt) { + return SmallInt.wrap(1) + SmallInt.wrap(2); + } + + function big() public pure returns (BigInt) { + return BigInt.wrap(3) + BigInt.wrap(4); + } +} +// ---- +// small() -> 3 +// big() -> 70 diff --git a/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives_standard_input.json b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives_standard_input.json new file mode 100644 index 00000000..5bff8c29 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_different_types_different_functions_separate_directives/multiple_operator_definitions_different_types_different_functions_separate_directives_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive.sol b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive.sol new file mode 100644 index 00000000..3085d8e8 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive.sol @@ -0,0 +1,20 @@ +type Int is int32; + +using {foo as +, foo as -} for Int global; + +function foo(Int a, Int b) pure returns(Int) { + return Int.wrap(Int.unwrap(a) + Int.unwrap(b)); +} + +contract C { + function f() pure public returns (Int) { + return Int.wrap(2) + Int.wrap(3); + } + + function g() pure public returns (Int) { + return Int.wrap(6) - Int.wrap(1); + } +} +// ---- +// f() -> 5 +// g() -> 7 diff --git a/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive_standard_input.json b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive_standard_input.json new file mode 100644 index 00000000..d016397f --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_multiple_operator_definitions_same_type_same_function_same_directive/multiple_operator_definitions_same_type_same_function_same_directive_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256.sol b/examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256.sol new file mode 100644 index 00000000..a26a750c --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256.sol @@ -0,0 +1,15 @@ +type Int is int16; + +using {keccak256 as +} for Int global; + +function keccak256(Int a, Int b) pure returns (Int) { + return Int.wrap(Int.unwrap(a) + Int.unwrap(b)); +} + +contract C { + function test() public returns (Int) { + return Int.wrap(3) + Int.wrap(4); + } +} +// ---- +// test() -> 7 diff --git a/examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256_standard_input.json new file mode 100644 index 00000000..002d335b --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_definition_shadowing_builtin_keccak256/operator_definition_shadowing_builtin_keccak256_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order.sol b/examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order.sol new file mode 100644 index 00000000..781f21d1 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order.sol @@ -0,0 +1,83 @@ +type Bool is bool; +using {add as +, mul as *, unsub as -} for Bool global; + +function add(Bool x, Bool y) pure returns (Bool) { + return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y)); +} + +function mul(Bool x, Bool y) pure returns (Bool) { + return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y)); +} + +function unsub(Bool x) pure returns (Bool) { + return Bool.wrap(!Bool.unwrap(x)); +} + +contract C { + event Wrapped(uint); + event Probe(Bool); + + function toBool(uint x) public returns (Bool) { + emit Wrapped(x); + return Bool.wrap(x > 0); + } + + function probe(Bool x) public returns (Bool) { + emit Probe(x); + return x; + } + + function testSingleOperator() public { + toBool(0) + + (toBool(1) + toBool(2)) + + toBool(3); + } + + function testTwoBinaryOperators() public { + toBool(0) * toBool(1) + + (toBool(2) * toBool(3)) + + toBool(4) * toBool(5); + } + + function testBinaryAndUnaryOperators() public { + -toBool(0) * -toBool(1) + + (-toBool(2) * -toBool(3)) + + -toBool(4) * -toBool(5); + } + + function testOperatorsNestedInCalls() public { + -probe(toBool(0) * -toBool(1)) + + (-probe(toBool(2) * -toBool(3))) + + -probe(toBool(4) * -toBool(5)); + } +} +// ---- +// testSingleOperator() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// testTwoBinaryOperators() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// ~ emit Wrapped(uint256): 0x04 +// ~ emit Wrapped(uint256): 0x05 +// testBinaryAndUnaryOperators() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// ~ emit Wrapped(uint256): 0x04 +// ~ emit Wrapped(uint256): 0x05 +// testOperatorsNestedInCalls() -> +// ~ emit Wrapped(uint256): 0x00 +// ~ emit Wrapped(uint256): 0x01 +// ~ emit Probe(bool): 0x00 +// ~ emit Wrapped(uint256): 0x02 +// ~ emit Wrapped(uint256): 0x03 +// ~ emit Probe(bool): 0x00 +// ~ emit Wrapped(uint256): 0x04 +// ~ emit Wrapped(uint256): 0x05 +// ~ emit Probe(bool): 0x00 diff --git a/examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order_standard_input.json new file mode 100644 index 00000000..2e64022e --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_evaluation_order/operator_evaluation_order_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + }, + "operator_evaluation_order.sol": { + "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n event Wrapped(uint);\n event Probe(Bool);\n\n function toBool(uint x) public returns (Bool) {\n emit Wrapped(x);\n return Bool.wrap(x > 0);\n }\n\n function probe(Bool x) public returns (Bool) {\n emit Probe(x);\n return x;\n }\n\n function testSingleOperator() public {\n toBool(0) +\n (toBool(1) + toBool(2)) +\n toBool(3);\n }\n\n function testTwoBinaryOperators() public {\n toBool(0) * toBool(1) +\n (toBool(2) * toBool(3)) +\n toBool(4) * toBool(5);\n }\n\n function testBinaryAndUnaryOperators() public {\n -toBool(0) * -toBool(1) +\n (-toBool(2) * -toBool(3)) +\n -toBool(4) * -toBool(5);\n }\n\n function testOperatorsNestedInCalls() public {\n -probe(toBool(0) * -toBool(1)) +\n (-probe(toBool(2) * -toBool(3))) +\n -probe(toBool(4) * -toBool(5));\n }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call.sol b/examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call.sol new file mode 100644 index 00000000..ec41099e --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call.sol @@ -0,0 +1,65 @@ +type Int32 is int32; +using {add as +, unsub as -} for Int32 global; + +function add(Int32 x, Int32 y) pure returns (Int32) { + return loadAdder().mul(x, y); +} + +function unsub(Int32 x) pure returns (Int32) { + return loadAdder().inc(x); +} + +interface IAdder { + function mul(Int32, Int32) external pure returns (Int32); + function inc(Int32) external pure returns (Int32); +} + +contract Adder is IAdder { + function mul(Int32 x, Int32 y) external pure override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y)); + } + + function inc(Int32 x) external pure override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) + 1); + } +} + +function storeAdder(IAdder adder) pure { + assembly { + // This test would also work without assembly if we could hard-code an address here. + mstore(0, adder) + } +} + +function loadAdder() pure returns (IAdder adder) { + assembly { + adder := mload(0) + } +} + +contract C { + function testMul(Int32 x, Int32 y) public returns (Int32) { + storeAdder(new Adder()); + + return x + y; + } + + function testInc(Int32 x) public returns (Int32) { + storeAdder(new Adder()); + + return -x; + } +} +// ---- +// testMul(int32,int32): 42, 10 -> 420 +// gas irOptimized: 102563 +// gas legacy: 56978 +// gas legacy code: 127000 +// gas legacyOptimized: 55161 +// gas legacyOptimized code: 68400 +// testInc(int32): 42 -> 43 +// gas irOptimized: 102386 +// gas legacy: 56238 +// gas legacy code: 127000 +// gas legacyOptimized: 54851 +// gas legacyOptimized code: 68400 diff --git a/examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call_standard_input.json new file mode 100644 index 00000000..66313f84 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_making_pure_external_call/operator_making_pure_external_call_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call.sol b/examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call.sol new file mode 100644 index 00000000..7e70eb09 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call.sol @@ -0,0 +1,71 @@ +type Int32 is int32; +using {add as +, unsub as -} for Int32 global; + +function add(Int32 x, Int32 y) pure returns (Int32) { + return loadAdder().mul(x, y); +} + +function unsub(Int32 x) pure returns (Int32) { + return loadAdder().inc(x); +} + +interface IAdderPure { + function mul(Int32, Int32) external pure returns (Int32); + function inc(Int32) external pure returns (Int32); +} + +interface IAdderView { + function mul(Int32, Int32) external view returns (Int32); + function inc(Int32) external view returns (Int32); +} + +contract Adder is IAdderView { + function mul(Int32 x, Int32 y) external view override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y)); + } + + function inc(Int32 x) external view override returns (Int32) { + return Int32.wrap(Int32.unwrap(x) + 1); + } +} + +function storeAdder(IAdderView adder) pure { + assembly { + // This test would also work without assembly if we could hard-code an address here. + mstore(0, adder) + } +} + +function loadAdder() pure returns (IAdderPure adder) { + assembly { + // The adder we stored is view but we cheat by using a modified version with pure functions + adder := mload(0) + } +} + +contract C { + function testMul(Int32 x, Int32 y) public returns (Int32) { + storeAdder(new Adder()); + + return x + y; + } + + function testInc(Int32 x) public returns (Int32) { + storeAdder(new Adder()); + + return -x; + } +} +// ---- +// testMul(int32,int32): 42, 10 -> 420 +// gas irOptimized: 102563 +// gas legacy: 56978 +// gas legacy code: 127000 +// gas legacyOptimized: 55161 +// gas legacyOptimized code: 68400 +// testInc(int32): 42 -> 43 +// gas irOptimized: 102386 +// gas legacy: 56238 +// gas legacy code: 127000 +// gas legacyOptimized: 54851 +// gas legacyOptimized code: 68400 diff --git a/examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call_standard_input.json new file mode 100644 index 00000000..d15eab54 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_making_view_external_call/operator_making_view_external_call_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls.sol b/examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls.sol new file mode 100644 index 00000000..b51ad8da --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls.sol @@ -0,0 +1,22 @@ +type U8 is uint8; +using {yoloAdd as +, yoloDiv as /} for U8 global; + +function yoloAdd(U8 x, U8 y) pure returns (U8 z) { + assembly { + z := add(x, y) // Wrong! No cleanup. + } +} + +function yoloDiv(U8 x, U8 y) pure returns (U8 z) { + assembly { + z := div(x, y) // Wrong! No cleanup. + } +} + +contract C { + function divAddNoOverflow(U8 a, U8 b, U8 c) external pure returns (U8) { + return a / (b + c); + } +} +// ---- +// divAddNoOverflow(uint8,uint8,uint8): 4, 0xff, 3 -> 0 diff --git a/examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls_standard_input.json new file mode 100644 index 00000000..f20b27b9 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_parameter_and_return_cleanup_between_calls/operator_parameter_and_return_cleanup_between_calls_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + }, + "operator_evaluation_order.sol": { + "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n event Wrapped(uint);\n event Probe(Bool);\n\n function toBool(uint x) public returns (Bool) {\n emit Wrapped(x);\n return Bool.wrap(x > 0);\n }\n\n function probe(Bool x) public returns (Bool) {\n emit Probe(x);\n return x;\n }\n\n function testSingleOperator() public {\n toBool(0) +\n (toBool(1) + toBool(2)) +\n toBool(3);\n }\n\n function testTwoBinaryOperators() public {\n toBool(0) * toBool(1) +\n (toBool(2) * toBool(3)) +\n toBool(4) * toBool(5);\n }\n\n function testBinaryAndUnaryOperators() public {\n -toBool(0) * -toBool(1) +\n (-toBool(2) * -toBool(3)) +\n -toBool(4) * -toBool(5);\n }\n\n function testOperatorsNestedInCalls() public {\n -probe(toBool(0) * -toBool(1)) +\n (-probe(toBool(2) * -toBool(3))) +\n -probe(toBool(4) * -toBool(5));\n }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n" + }, + "recursive_operator.sol": { + "content": "type Uint is uint;\nusing {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global;\n\nfunction unaryCountdown(Uint x) pure returns (Uint) {\n if (x == Uint.wrap(0))\n return Uint.wrap(0);\n\n return ~Uint.wrap(Uint.unwrap(x) - 1);\n}\n\nfunction binaryCountdown(Uint x, Uint y) pure returns (Uint) {\n if (x == Uint.wrap(0) && y == Uint.wrap(0))\n return Uint.wrap(0);\n if (x == Uint.wrap(0))\n return y ^ x;\n\n return Uint.wrap(Uint.unwrap(x) - 1) ^ y;\n}\n\nfunction eq(Uint x, Uint y) pure returns (bool) {\n return Uint.unwrap(x) == Uint.unwrap(y);\n}\n\ncontract C {\n function testUnary(Uint x) public pure returns (Uint) {\n return ~x;\n }\n\n function testBinary(Uint x, Uint y) public pure returns (Uint) {\n return x ^ y;\n }\n}\n// ----\n// testUnary(uint256): 0 -> 0\n// testUnary(uint256): 1 -> 0\n// testUnary(uint256): 99999999999 -> FAILURE\n// testBinary(uint256,uint256): 0, 0 -> 0\n// testBinary(uint256,uint256): 1, 0 -> 0\n// testBinary(uint256,uint256): 0, 1 -> 0\n// testBinary(uint256,uint256): 1, 1 -> 0\n// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE\n" + }, + "operator_parameter_and_return_cleanup_between_calls.sol": { + "content": "type U8 is uint8;\nusing {yoloAdd as +, yoloDiv as /} for U8 global;\n\nfunction yoloAdd(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := add(x, y) // Wrong! No cleanup.\n }\n}\n\nfunction yoloDiv(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := div(x, y) // Wrong! No cleanup.\n }\n}\n\ncontract C {\n function divAddNoOverflow(U8 a, U8 b, U8 c) external pure returns (U8) {\n return a / (b + c);\n }\n}\n// ----\n// divAddNoOverflow(uint8,uint8,uint8): 4, 0xff, 3 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup.sol b/examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup.sol new file mode 100644 index 00000000..fe37a0e1 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup.sol @@ -0,0 +1,40 @@ +type U8 is uint8; +using {f as ~, add as +} for U8 global; + +function f(U8 x) pure returns (U8 z) { + assembly { + // NOTE: Not using shr so that the test works pre-constantinople too + z := div(x, 256) + } +} + +function add(U8 x, U8 y) pure returns (U8 z) { + assembly { + z := add(div(x, 256), div(x, 256)) + } +} + +contract C { + function testUnary() external pure returns (U8, U8) { + U8 a; + assembly { + a := 0x4200 + } + // If the result is not 0, no cleanup was performed. + return (~a, f(a)); + } + + function testBinary() external pure returns (U8, U8) { + U8 a; + U8 b; + assembly { + a := 0x4200 + b := 0x4200 + } + // If the result is not 0, no cleanup was performed. + return (a + b, add(a, b)); + } +} +// ---- +// testUnary() -> 0x42, 0x42 +// testBinary() -> 0x84, 0x84 diff --git a/examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup_standard_input.json new file mode 100644 index 00000000..fad0b139 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_parameter_cleanup/operator_parameter_cleanup_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + }, + "operator_evaluation_order.sol": { + "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n event Wrapped(uint);\n event Probe(Bool);\n\n function toBool(uint x) public returns (Bool) {\n emit Wrapped(x);\n return Bool.wrap(x > 0);\n }\n\n function probe(Bool x) public returns (Bool) {\n emit Probe(x);\n return x;\n }\n\n function testSingleOperator() public {\n toBool(0) +\n (toBool(1) + toBool(2)) +\n toBool(3);\n }\n\n function testTwoBinaryOperators() public {\n toBool(0) * toBool(1) +\n (toBool(2) * toBool(3)) +\n toBool(4) * toBool(5);\n }\n\n function testBinaryAndUnaryOperators() public {\n -toBool(0) * -toBool(1) +\n (-toBool(2) * -toBool(3)) +\n -toBool(4) * -toBool(5);\n }\n\n function testOperatorsNestedInCalls() public {\n -probe(toBool(0) * -toBool(1)) +\n (-probe(toBool(2) * -toBool(3))) +\n -probe(toBool(4) * -toBool(5));\n }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n" + }, + "recursive_operator.sol": { + "content": "type Uint is uint;\nusing {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global;\n\nfunction unaryCountdown(Uint x) pure returns (Uint) {\n if (x == Uint.wrap(0))\n return Uint.wrap(0);\n\n return ~Uint.wrap(Uint.unwrap(x) - 1);\n}\n\nfunction binaryCountdown(Uint x, Uint y) pure returns (Uint) {\n if (x == Uint.wrap(0) && y == Uint.wrap(0))\n return Uint.wrap(0);\n if (x == Uint.wrap(0))\n return y ^ x;\n\n return Uint.wrap(Uint.unwrap(x) - 1) ^ y;\n}\n\nfunction eq(Uint x, Uint y) pure returns (bool) {\n return Uint.unwrap(x) == Uint.unwrap(y);\n}\n\ncontract C {\n function testUnary(Uint x) public pure returns (Uint) {\n return ~x;\n }\n\n function testBinary(Uint x, Uint y) public pure returns (Uint) {\n return x ^ y;\n }\n}\n// ----\n// testUnary(uint256): 0 -> 0\n// testUnary(uint256): 1 -> 0\n// testUnary(uint256): 99999999999 -> FAILURE\n// testBinary(uint256,uint256): 0, 0 -> 0\n// testBinary(uint256,uint256): 1, 0 -> 0\n// testBinary(uint256,uint256): 0, 1 -> 0\n// testBinary(uint256,uint256): 1, 1 -> 0\n// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE\n" + }, + "operator_parameter_and_return_cleanup_between_calls.sol": { + "content": "type U8 is uint8;\nusing {yoloAdd as +, yoloDiv as /} for U8 global;\n\nfunction yoloAdd(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := add(x, y) // Wrong! No cleanup.\n }\n}\n\nfunction yoloDiv(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := div(x, y) // Wrong! No cleanup.\n }\n}\n\ncontract C {\n function divAddNoOverflow(U8 a, U8 b, U8 c) external pure returns (U8) {\n return a / (b + c);\n }\n}\n// ----\n// divAddNoOverflow(uint8,uint8,uint8): 4, 0xff, 3 -> 0\n" + }, + "operator_precendence.sol": { + "content": "type Int is int64;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\ncontract C {\n Int constant I0 = Int.wrap(0);\n Int constant I1 = Int.wrap(1);\n Int constant I2 = Int.wrap(2);\n Int constant I3 = Int.wrap(3);\n Int constant I4 = Int.wrap(4);\n Int constant I5 = Int.wrap(5);\n Int constant I6 = Int.wrap(6);\n Int constant I7 = Int.wrap(7);\n Int constant I8 = Int.wrap(8);\n Int constant I10 = Int.wrap(10);\n Int constant I13 = Int.wrap(13);\n Int constant I15 = Int.wrap(15);\n Int constant I20 = Int.wrap(20);\n Int constant I128 = Int.wrap(128);\n\n function testBitwise() public pure {\n assert(Int.unwrap(I0 & I0 | I1) == (0 & 0 | 1));\n assert(Int.unwrap(I0 & I0 | I1) == ((0 & 0) | 1));\n }\n\n function testBitwise_arithmetic() public pure {\n assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (2 + 2 & ~1 | 6 * 6 - 4 & ~3));\n assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (((2 + 2) & (~1)) | (((6 * 6) - 4) & (~3))));\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == (1 + 8 / 4 - 5 % 6 * 7));\n assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == ((1 + (8 / 4)) - ((5 % 6) * 7)));\n }\n\n function testAll() public pure {\n assert(\n Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n (128 + 1 - 10 + 4 & ~1 ^ ~1 * 2 | -15 % -10 * 20 / 2 + 13 & ~3)\n );\n assert(\n Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n (\n (\n ((((128 + 1) - 10) + 4) & (~1)) ^\n ((~1) * 2)\n ) |\n ((((((-15) % (-10)) * 20) / 2) + 13) & (~3))\n )\n );\n }\n}\n// ----\n// testBitwise() ->\n// testBitwise_arithmetic() ->\n// testArithmetic() ->\n// testAll() ->\n" + }, + "attaching_and_defining_operator_with_same_function.sol": { + "content": "type Int is int16;\n\nusing {add as +, add} for Int global;\n\nfunction add(Int _a, Int _b) pure returns (Int) {\n return Int.wrap(Int.unwrap(_a) + Int.unwrap(_b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(5) + Int.wrap(5);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(7).add(Int.wrap(6));\n }\n}\n// ----\n// f() -> 10\n// g() -> 13\n" + }, + "operator_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, add as +} for U8 global;\n\nfunction f(U8 x) pure returns (U8 z) {\n assembly {\n // NOTE: Not using shr so that the test works pre-constantinople too\n z := div(x, 256)\n }\n}\n\nfunction add(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := add(div(x, 256), div(x, 256))\n }\n}\n\ncontract C {\n function testUnary() external pure returns (U8, U8) {\n U8 a;\n assembly {\n a := 0x4200\n }\n // If the result is not 0, no cleanup was performed.\n return (~a, f(a));\n }\n\n function testBinary() external pure returns (U8, U8) {\n U8 a;\n U8 b;\n assembly {\n a := 0x4200\n b := 0x4200\n }\n // If the result is not 0, no cleanup was performed.\n return (a + b, add(a, b));\n }\n}\n// ----\n// testUnary() -> 0x42, 0x42\n// testBinary() -> 0x84, 0x84\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence.sol b/examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence.sol new file mode 100644 index 00000000..961e0316 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence.sol @@ -0,0 +1,71 @@ +type Int is int64; +using { + bitor as |, bitand as &, bitxor as ^, bitnot as ~, + add as +, sub as -, unsub as -, mul as *, div as /, mod as % +} for Int global; + +function bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); } +function bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); } +function bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); } +function bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); } + +function add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); } +function sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); } +function unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); } +function mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); } +function div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); } +function mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); } + +contract C { + Int constant I0 = Int.wrap(0); + Int constant I1 = Int.wrap(1); + Int constant I2 = Int.wrap(2); + Int constant I3 = Int.wrap(3); + Int constant I4 = Int.wrap(4); + Int constant I5 = Int.wrap(5); + Int constant I6 = Int.wrap(6); + Int constant I7 = Int.wrap(7); + Int constant I8 = Int.wrap(8); + Int constant I10 = Int.wrap(10); + Int constant I13 = Int.wrap(13); + Int constant I15 = Int.wrap(15); + Int constant I20 = Int.wrap(20); + Int constant I128 = Int.wrap(128); + + function testBitwise() public pure { + assert(Int.unwrap(I0 & I0 | I1) == (0 & 0 | 1)); + assert(Int.unwrap(I0 & I0 | I1) == ((0 & 0) | 1)); + } + + function testBitwise_arithmetic() public pure { + assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (2 + 2 & ~1 | 6 * 6 - 4 & ~3)); + assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (((2 + 2) & (~1)) | (((6 * 6) - 4) & (~3)))); + } + + function testArithmetic() public pure { + assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == (1 + 8 / 4 - 5 % 6 * 7)); + assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == ((1 + (8 / 4)) - ((5 % 6) * 7))); + } + + function testAll() public pure { + assert( + Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) == + (128 + 1 - 10 + 4 & ~1 ^ ~1 * 2 | -15 % -10 * 20 / 2 + 13 & ~3) + ); + assert( + Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) == + ( + ( + ((((128 + 1) - 10) + 4) & (~1)) ^ + ((~1) * 2) + ) | + ((((((-15) % (-10)) * 20) / 2) + 13) & (~3)) + ) + ); + } +} +// ---- +// testBitwise() -> +// testBitwise_arithmetic() -> +// testArithmetic() -> +// testAll() -> diff --git a/examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence_standard_input.json new file mode 100644 index 00000000..b17f623d --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_precendence/operator_precendence_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + }, + "operator_evaluation_order.sol": { + "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n event Wrapped(uint);\n event Probe(Bool);\n\n function toBool(uint x) public returns (Bool) {\n emit Wrapped(x);\n return Bool.wrap(x > 0);\n }\n\n function probe(Bool x) public returns (Bool) {\n emit Probe(x);\n return x;\n }\n\n function testSingleOperator() public {\n toBool(0) +\n (toBool(1) + toBool(2)) +\n toBool(3);\n }\n\n function testTwoBinaryOperators() public {\n toBool(0) * toBool(1) +\n (toBool(2) * toBool(3)) +\n toBool(4) * toBool(5);\n }\n\n function testBinaryAndUnaryOperators() public {\n -toBool(0) * -toBool(1) +\n (-toBool(2) * -toBool(3)) +\n -toBool(4) * -toBool(5);\n }\n\n function testOperatorsNestedInCalls() public {\n -probe(toBool(0) * -toBool(1)) +\n (-probe(toBool(2) * -toBool(3))) +\n -probe(toBool(4) * -toBool(5));\n }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n" + }, + "recursive_operator.sol": { + "content": "type Uint is uint;\nusing {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global;\n\nfunction unaryCountdown(Uint x) pure returns (Uint) {\n if (x == Uint.wrap(0))\n return Uint.wrap(0);\n\n return ~Uint.wrap(Uint.unwrap(x) - 1);\n}\n\nfunction binaryCountdown(Uint x, Uint y) pure returns (Uint) {\n if (x == Uint.wrap(0) && y == Uint.wrap(0))\n return Uint.wrap(0);\n if (x == Uint.wrap(0))\n return y ^ x;\n\n return Uint.wrap(Uint.unwrap(x) - 1) ^ y;\n}\n\nfunction eq(Uint x, Uint y) pure returns (bool) {\n return Uint.unwrap(x) == Uint.unwrap(y);\n}\n\ncontract C {\n function testUnary(Uint x) public pure returns (Uint) {\n return ~x;\n }\n\n function testBinary(Uint x, Uint y) public pure returns (Uint) {\n return x ^ y;\n }\n}\n// ----\n// testUnary(uint256): 0 -> 0\n// testUnary(uint256): 1 -> 0\n// testUnary(uint256): 99999999999 -> FAILURE\n// testBinary(uint256,uint256): 0, 0 -> 0\n// testBinary(uint256,uint256): 1, 0 -> 0\n// testBinary(uint256,uint256): 0, 1 -> 0\n// testBinary(uint256,uint256): 1, 1 -> 0\n// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE\n" + }, + "operator_parameter_and_return_cleanup_between_calls.sol": { + "content": "type U8 is uint8;\nusing {yoloAdd as +, yoloDiv as /} for U8 global;\n\nfunction yoloAdd(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := add(x, y) // Wrong! No cleanup.\n }\n}\n\nfunction yoloDiv(U8 x, U8 y) pure returns (U8 z) {\n assembly {\n z := div(x, y) // Wrong! No cleanup.\n }\n}\n\ncontract C {\n function divAddNoOverflow(U8 a, U8 b, U8 c) external pure returns (U8) {\n return a / (b + c);\n }\n}\n// ----\n// divAddNoOverflow(uint8,uint8,uint8): 4, 0xff, 3 -> 0\n" + }, + "operator_precendence.sol": { + "content": "type Int is int64;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\ncontract C {\n Int constant I0 = Int.wrap(0);\n Int constant I1 = Int.wrap(1);\n Int constant I2 = Int.wrap(2);\n Int constant I3 = Int.wrap(3);\n Int constant I4 = Int.wrap(4);\n Int constant I5 = Int.wrap(5);\n Int constant I6 = Int.wrap(6);\n Int constant I7 = Int.wrap(7);\n Int constant I8 = Int.wrap(8);\n Int constant I10 = Int.wrap(10);\n Int constant I13 = Int.wrap(13);\n Int constant I15 = Int.wrap(15);\n Int constant I20 = Int.wrap(20);\n Int constant I128 = Int.wrap(128);\n\n function testBitwise() public pure {\n assert(Int.unwrap(I0 & I0 | I1) == (0 & 0 | 1));\n assert(Int.unwrap(I0 & I0 | I1) == ((0 & 0) | 1));\n }\n\n function testBitwise_arithmetic() public pure {\n assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (2 + 2 & ~1 | 6 * 6 - 4 & ~3));\n assert(Int.unwrap(I2 + I2 & ~I1 | I6 * I6 - I4 & ~I3) == (((2 + 2) & (~1)) | (((6 * 6) - 4) & (~3))));\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == (1 + 8 / 4 - 5 % 6 * 7));\n assert(Int.unwrap(I1 + I8 / I4 - I5 % I6 * I7) == ((1 + (8 / 4)) - ((5 % 6) * 7)));\n }\n\n function testAll() public pure {\n assert(\n Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n (128 + 1 - 10 + 4 & ~1 ^ ~1 * 2 | -15 % -10 * 20 / 2 + 13 & ~3)\n );\n assert(\n Int.unwrap(I128 + I1 - I10 + I4 & ~I1 ^ ~I1 * I2 | -I15 % -I10 * I20 / I2 + I13 & ~I3) ==\n (\n (\n ((((128 + 1) - 10) + 4) & (~1)) ^\n ((~1) * 2)\n ) |\n ((((((-15) % (-10)) * 20) / 2) + 13) & (~3))\n )\n );\n }\n}\n// ----\n// testBitwise() ->\n// testBitwise_arithmetic() ->\n// testArithmetic() ->\n// testAll() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup.sol b/examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup.sol new file mode 100644 index 00000000..3798a003 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup.sol @@ -0,0 +1,58 @@ +type U8 is uint8; +using {f as ~, g as +} for U8 global; + +function f(U8) pure returns (U8 z) { + assembly { + // Return a value with dirty bytes outside of uint8 + z := 0xffff + } +} + +function g(U8, U8) pure returns (U8 z) { + assembly { + // Return a value with dirty bytes outside of uint8 + z := 0xffff + } +} + +contract C { + function testUnary() external pure returns (uint, uint) { + U8 a; // Value does not matter + + U8 opResult = ~a; + U8 fResult = f(a); + + // Get the slot, including bytes outside of uint8 + uint opResultFull; + uint fResultFull; + assembly { + opResultFull := opResult + fResultFull := fResult + } + + // If the result is not 0xff, no cleanup was performed. + return (opResultFull, fResultFull); + } + + function testBinary() external pure returns (uint, uint) { + U8 a; // Value does not matter + U8 b; // Value does not matter + + U8 opResult = a + b; + U8 fResult = g(a, b); + + // Get the slot, including bytes outside of uint8 + uint opResultFull; + uint fResultFull; + assembly { + opResultFull := opResult + fResultFull := fResult + } + + // If the result is not 0xff, no cleanup was performed. + return (opResultFull, fResultFull); + } +} +// ---- +// testUnary() -> 0xffff, 0xffff +// testBinary() -> 0xffff, 0xffff diff --git a/examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup_standard_input.json b/examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup_standard_input.json new file mode 100644 index 00000000..1110ae1f --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_operator_return_parameter_cleanup/operator_return_parameter_cleanup_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator.sol b/examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator.sol new file mode 100644 index 00000000..3ce080c3 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator.sol @@ -0,0 +1,41 @@ +type Uint is uint; +using {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global; + +function unaryCountdown(Uint x) pure returns (Uint) { + if (x == Uint.wrap(0)) + return Uint.wrap(0); + + return ~Uint.wrap(Uint.unwrap(x) - 1); +} + +function binaryCountdown(Uint x, Uint y) pure returns (Uint) { + if (x == Uint.wrap(0) && y == Uint.wrap(0)) + return Uint.wrap(0); + if (x == Uint.wrap(0)) + return y ^ x; + + return Uint.wrap(Uint.unwrap(x) - 1) ^ y; +} + +function eq(Uint x, Uint y) pure returns (bool) { + return Uint.unwrap(x) == Uint.unwrap(y); +} + +contract C { + function testUnary(Uint x) public pure returns (Uint) { + return ~x; + } + + function testBinary(Uint x, Uint y) public pure returns (Uint) { + return x ^ y; + } +} +// ---- +// testUnary(uint256): 0 -> 0 +// testUnary(uint256): 1 -> 0 +// testUnary(uint256): 99999999999 -> FAILURE +// testBinary(uint256,uint256): 0, 0 -> 0 +// testBinary(uint256,uint256): 1, 0 -> 0 +// testBinary(uint256,uint256): 0, 1 -> 0 +// testBinary(uint256,uint256): 1, 1 -> 0 +// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE diff --git a/examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator_standard_input.json b/examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator_standard_input.json new file mode 100644 index 00000000..fd983f8f --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_recursive_operator/recursive_operator_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + }, + "all_possible_user_defined_value_types_with_operators.sol": { + "content": "type Int8 is int8;\ntype Int16 is int16;\ntype Int24 is int24;\ntype Int32 is int32;\ntype Int40 is int40;\ntype Int48 is int48;\ntype Int56 is int56;\ntype Int64 is int64;\ntype Int72 is int72;\ntype Int80 is int80;\ntype Int88 is int88;\ntype Int96 is int96;\ntype Int104 is int104;\ntype Int112 is int112;\ntype Int120 is int120;\ntype Int128 is int128;\ntype Int136 is int136;\ntype Int144 is int144;\ntype Int152 is int152;\ntype Int160 is int160;\ntype Int168 is int168;\ntype Int176 is int176;\ntype Int184 is int184;\ntype Int192 is int192;\ntype Int200 is int200;\ntype Int208 is int208;\ntype Int216 is int216;\ntype Int224 is int224;\ntype Int232 is int232;\ntype Int240 is int240;\ntype Int248 is int248;\ntype Int256 is int256;\ntype Int is int;\n\ntype Uint8 is uint8;\ntype Uint16 is uint16;\ntype Uint24 is uint24;\ntype Uint32 is uint32;\ntype Uint40 is uint40;\ntype Uint48 is uint48;\ntype Uint56 is uint56;\ntype Uint64 is uint64;\ntype Uint72 is uint72;\ntype Uint80 is uint80;\ntype Uint88 is uint88;\ntype Uint96 is uint96;\ntype Uint104 is uint104;\ntype Uint112 is uint112;\ntype Uint120 is uint120;\ntype Uint128 is uint128;\ntype Uint136 is uint136;\ntype Uint144 is uint144;\ntype Uint152 is uint152;\ntype Uint160 is uint160;\ntype Uint168 is uint168;\ntype Uint176 is uint176;\ntype Uint184 is uint184;\ntype Uint192 is uint192;\ntype Uint200 is uint200;\ntype Uint208 is uint208;\ntype Uint216 is uint216;\ntype Uint224 is uint224;\ntype Uint232 is uint232;\ntype Uint240 is uint240;\ntype Uint248 is uint248;\ntype Uint256 is uint256;\ntype Uint is uint;\n\ntype Bytes1 is bytes1;\ntype Bytes2 is bytes2;\ntype Bytes3 is bytes3;\ntype Bytes4 is bytes4;\ntype Bytes5 is bytes5;\ntype Bytes6 is bytes6;\ntype Bytes7 is bytes7;\ntype Bytes8 is bytes8;\ntype Bytes9 is bytes9;\ntype Bytes10 is bytes10;\ntype Bytes11 is bytes11;\ntype Bytes12 is bytes12;\ntype Bytes13 is bytes13;\ntype Bytes14 is bytes14;\ntype Bytes15 is bytes15;\ntype Bytes16 is bytes16;\ntype Bytes17 is bytes17;\ntype Bytes18 is bytes18;\ntype Bytes19 is bytes19;\ntype Bytes20 is bytes20;\ntype Bytes21 is bytes21;\ntype Bytes22 is bytes22;\ntype Bytes23 is bytes23;\ntype Bytes24 is bytes24;\ntype Bytes25 is bytes25;\ntype Bytes26 is bytes26;\ntype Bytes27 is bytes27;\ntype Bytes28 is bytes28;\ntype Bytes29 is bytes29;\ntype Bytes30 is bytes30;\ntype Bytes31 is bytes31;\ntype Bytes32 is bytes32;\n\ntype Address is address;\ntype AddressPayable is address payable;\n\ntype Bool is bool;\n\nusing {bitorInt8 as |, unsubInt8 as -} for Int8 global;\nusing {bitorInt16 as |, unsubInt16 as -} for Int16 global;\nusing {bitorInt24 as |, unsubInt24 as -} for Int24 global;\nusing {bitorInt32 as |, unsubInt32 as -} for Int32 global;\nusing {bitorInt40 as |, unsubInt40 as -} for Int40 global;\nusing {bitorInt48 as |, unsubInt48 as -} for Int48 global;\nusing {bitorInt56 as |, unsubInt56 as -} for Int56 global;\nusing {bitorInt64 as |, unsubInt64 as -} for Int64 global;\nusing {bitorInt72 as |, unsubInt72 as -} for Int72 global;\nusing {bitorInt80 as |, unsubInt80 as -} for Int80 global;\nusing {bitorInt88 as |, unsubInt88 as -} for Int88 global;\nusing {bitorInt96 as |, unsubInt96 as -} for Int96 global;\nusing {bitorInt104 as |, unsubInt104 as -} for Int104 global;\nusing {bitorInt112 as |, unsubInt112 as -} for Int112 global;\nusing {bitorInt120 as |, unsubInt120 as -} for Int120 global;\nusing {bitorInt128 as |, unsubInt128 as -} for Int128 global;\nusing {bitorInt136 as |, unsubInt136 as -} for Int136 global;\nusing {bitorInt144 as |, unsubInt144 as -} for Int144 global;\nusing {bitorInt152 as |, unsubInt152 as -} for Int152 global;\nusing {bitorInt160 as |, unsubInt160 as -} for Int160 global;\nusing {bitorInt168 as |, unsubInt168 as -} for Int168 global;\nusing {bitorInt176 as |, unsubInt176 as -} for Int176 global;\nusing {bitorInt184 as |, unsubInt184 as -} for Int184 global;\nusing {bitorInt192 as |, unsubInt192 as -} for Int192 global;\nusing {bitorInt200 as |, unsubInt200 as -} for Int200 global;\nusing {bitorInt208 as |, unsubInt208 as -} for Int208 global;\nusing {bitorInt216 as |, unsubInt216 as -} for Int216 global;\nusing {bitorInt224 as |, unsubInt224 as -} for Int224 global;\nusing {bitorInt232 as |, unsubInt232 as -} for Int232 global;\nusing {bitorInt240 as |, unsubInt240 as -} for Int240 global;\nusing {bitorInt248 as |, unsubInt248 as -} for Int248 global;\nusing {bitorInt256 as |, unsubInt256 as -} for Int256 global;\nusing {bitorInt as |, unsubInt as -} for Int global;\n\nusing {bitorUint8 as |, bitnotUint8 as ~} for Uint8 global;\nusing {bitorUint16 as |, bitnotUint16 as ~} for Uint16 global;\nusing {bitorUint24 as |, bitnotUint24 as ~} for Uint24 global;\nusing {bitorUint32 as |, bitnotUint32 as ~} for Uint32 global;\nusing {bitorUint40 as |, bitnotUint40 as ~} for Uint40 global;\nusing {bitorUint48 as |, bitnotUint48 as ~} for Uint48 global;\nusing {bitorUint56 as |, bitnotUint56 as ~} for Uint56 global;\nusing {bitorUint64 as |, bitnotUint64 as ~} for Uint64 global;\nusing {bitorUint72 as |, bitnotUint72 as ~} for Uint72 global;\nusing {bitorUint80 as |, bitnotUint80 as ~} for Uint80 global;\nusing {bitorUint88 as |, bitnotUint88 as ~} for Uint88 global;\nusing {bitorUint96 as |, bitnotUint96 as ~} for Uint96 global;\nusing {bitorUint104 as |, bitnotUint104 as ~} for Uint104 global;\nusing {bitorUint112 as |, bitnotUint112 as ~} for Uint112 global;\nusing {bitorUint120 as |, bitnotUint120 as ~} for Uint120 global;\nusing {bitorUint128 as |, bitnotUint128 as ~} for Uint128 global;\nusing {bitorUint136 as |, bitnotUint136 as ~} for Uint136 global;\nusing {bitorUint144 as |, bitnotUint144 as ~} for Uint144 global;\nusing {bitorUint152 as |, bitnotUint152 as ~} for Uint152 global;\nusing {bitorUint160 as |, bitnotUint160 as ~} for Uint160 global;\nusing {bitorUint168 as |, bitnotUint168 as ~} for Uint168 global;\nusing {bitorUint176 as |, bitnotUint176 as ~} for Uint176 global;\nusing {bitorUint184 as |, bitnotUint184 as ~} for Uint184 global;\nusing {bitorUint192 as |, bitnotUint192 as ~} for Uint192 global;\nusing {bitorUint200 as |, bitnotUint200 as ~} for Uint200 global;\nusing {bitorUint208 as |, bitnotUint208 as ~} for Uint208 global;\nusing {bitorUint216 as |, bitnotUint216 as ~} for Uint216 global;\nusing {bitorUint224 as |, bitnotUint224 as ~} for Uint224 global;\nusing {bitorUint232 as |, bitnotUint232 as ~} for Uint232 global;\nusing {bitorUint240 as |, bitnotUint240 as ~} for Uint240 global;\nusing {bitorUint248 as |, bitnotUint248 as ~} for Uint248 global;\nusing {bitorUint256 as |, bitnotUint256 as ~} for Uint256 global;\nusing {bitorUint as |, bitnotUint as ~} for Uint global;\n\nusing {bitorBytes1 as |, bitnotBytes1 as ~} for Bytes1 global;\nusing {bitorBytes2 as |, bitnotBytes2 as ~} for Bytes2 global;\nusing {bitorBytes3 as |, bitnotBytes3 as ~} for Bytes3 global;\nusing {bitorBytes4 as |, bitnotBytes4 as ~} for Bytes4 global;\nusing {bitorBytes5 as |, bitnotBytes5 as ~} for Bytes5 global;\nusing {bitorBytes6 as |, bitnotBytes6 as ~} for Bytes6 global;\nusing {bitorBytes7 as |, bitnotBytes7 as ~} for Bytes7 global;\nusing {bitorBytes8 as |, bitnotBytes8 as ~} for Bytes8 global;\nusing {bitorBytes9 as |, bitnotBytes9 as ~} for Bytes9 global;\nusing {bitorBytes10 as |, bitnotBytes10 as ~} for Bytes10 global;\nusing {bitorBytes11 as |, bitnotBytes11 as ~} for Bytes11 global;\nusing {bitorBytes12 as |, bitnotBytes12 as ~} for Bytes12 global;\nusing {bitorBytes13 as |, bitnotBytes13 as ~} for Bytes13 global;\nusing {bitorBytes14 as |, bitnotBytes14 as ~} for Bytes14 global;\nusing {bitorBytes15 as |, bitnotBytes15 as ~} for Bytes15 global;\nusing {bitorBytes16 as |, bitnotBytes16 as ~} for Bytes16 global;\nusing {bitorBytes17 as |, bitnotBytes17 as ~} for Bytes17 global;\nusing {bitorBytes18 as |, bitnotBytes18 as ~} for Bytes18 global;\nusing {bitorBytes19 as |, bitnotBytes19 as ~} for Bytes19 global;\nusing {bitorBytes20 as |, bitnotBytes20 as ~} for Bytes20 global;\nusing {bitorBytes21 as |, bitnotBytes21 as ~} for Bytes21 global;\nusing {bitorBytes22 as |, bitnotBytes22 as ~} for Bytes22 global;\nusing {bitorBytes23 as |, bitnotBytes23 as ~} for Bytes23 global;\nusing {bitorBytes24 as |, bitnotBytes24 as ~} for Bytes24 global;\nusing {bitorBytes25 as |, bitnotBytes25 as ~} for Bytes25 global;\nusing {bitorBytes26 as |, bitnotBytes26 as ~} for Bytes26 global;\nusing {bitorBytes27 as |, bitnotBytes27 as ~} for Bytes27 global;\nusing {bitorBytes28 as |, bitnotBytes28 as ~} for Bytes28 global;\nusing {bitorBytes29 as |, bitnotBytes29 as ~} for Bytes29 global;\nusing {bitorBytes30 as |, bitnotBytes30 as ~} for Bytes30 global;\nusing {bitorBytes31 as |, bitnotBytes31 as ~} for Bytes31 global;\nusing {bitorBytes32 as |, bitnotBytes32 as ~} for Bytes32 global;\n\nfunction bitorInt8(Int8 x, Int8 y) pure returns (Int8) { return Int8.wrap(Int8.unwrap(x) | Int8.unwrap(y)); }\nfunction bitorInt16(Int16 x, Int16 y) pure returns (Int16) { return Int16.wrap(Int16.unwrap(x) | Int16.unwrap(y)); }\nfunction bitorInt24(Int24 x, Int24 y) pure returns (Int24) { return Int24.wrap(Int24.unwrap(x) | Int24.unwrap(y)); }\nfunction bitorInt32(Int32 x, Int32 y) pure returns (Int32) { return Int32.wrap(Int32.unwrap(x) | Int32.unwrap(y)); }\nfunction bitorInt40(Int40 x, Int40 y) pure returns (Int40) { return Int40.wrap(Int40.unwrap(x) | Int40.unwrap(y)); }\nfunction bitorInt48(Int48 x, Int48 y) pure returns (Int48) { return Int48.wrap(Int48.unwrap(x) | Int48.unwrap(y)); }\nfunction bitorInt56(Int56 x, Int56 y) pure returns (Int56) { return Int56.wrap(Int56.unwrap(x) | Int56.unwrap(y)); }\nfunction bitorInt64(Int64 x, Int64 y) pure returns (Int64) { return Int64.wrap(Int64.unwrap(x) | Int64.unwrap(y)); }\nfunction bitorInt72(Int72 x, Int72 y) pure returns (Int72) { return Int72.wrap(Int72.unwrap(x) | Int72.unwrap(y)); }\nfunction bitorInt80(Int80 x, Int80 y) pure returns (Int80) { return Int80.wrap(Int80.unwrap(x) | Int80.unwrap(y)); }\nfunction bitorInt88(Int88 x, Int88 y) pure returns (Int88) { return Int88.wrap(Int88.unwrap(x) | Int88.unwrap(y)); }\nfunction bitorInt96(Int96 x, Int96 y) pure returns (Int96) { return Int96.wrap(Int96.unwrap(x) | Int96.unwrap(y)); }\nfunction bitorInt104(Int104 x, Int104 y) pure returns (Int104) { return Int104.wrap(Int104.unwrap(x) | Int104.unwrap(y)); }\nfunction bitorInt112(Int112 x, Int112 y) pure returns (Int112) { return Int112.wrap(Int112.unwrap(x) | Int112.unwrap(y)); }\nfunction bitorInt120(Int120 x, Int120 y) pure returns (Int120) { return Int120.wrap(Int120.unwrap(x) | Int120.unwrap(y)); }\nfunction bitorInt128(Int128 x, Int128 y) pure returns (Int128) { return Int128.wrap(Int128.unwrap(x) | Int128.unwrap(y)); }\nfunction bitorInt136(Int136 x, Int136 y) pure returns (Int136) { return Int136.wrap(Int136.unwrap(x) | Int136.unwrap(y)); }\nfunction bitorInt144(Int144 x, Int144 y) pure returns (Int144) { return Int144.wrap(Int144.unwrap(x) | Int144.unwrap(y)); }\nfunction bitorInt152(Int152 x, Int152 y) pure returns (Int152) { return Int152.wrap(Int152.unwrap(x) | Int152.unwrap(y)); }\nfunction bitorInt160(Int160 x, Int160 y) pure returns (Int160) { return Int160.wrap(Int160.unwrap(x) | Int160.unwrap(y)); }\nfunction bitorInt168(Int168 x, Int168 y) pure returns (Int168) { return Int168.wrap(Int168.unwrap(x) | Int168.unwrap(y)); }\nfunction bitorInt176(Int176 x, Int176 y) pure returns (Int176) { return Int176.wrap(Int176.unwrap(x) | Int176.unwrap(y)); }\nfunction bitorInt184(Int184 x, Int184 y) pure returns (Int184) { return Int184.wrap(Int184.unwrap(x) | Int184.unwrap(y)); }\nfunction bitorInt192(Int192 x, Int192 y) pure returns (Int192) { return Int192.wrap(Int192.unwrap(x) | Int192.unwrap(y)); }\nfunction bitorInt200(Int200 x, Int200 y) pure returns (Int200) { return Int200.wrap(Int200.unwrap(x) | Int200.unwrap(y)); }\nfunction bitorInt208(Int208 x, Int208 y) pure returns (Int208) { return Int208.wrap(Int208.unwrap(x) | Int208.unwrap(y)); }\nfunction bitorInt216(Int216 x, Int216 y) pure returns (Int216) { return Int216.wrap(Int216.unwrap(x) | Int216.unwrap(y)); }\nfunction bitorInt224(Int224 x, Int224 y) pure returns (Int224) { return Int224.wrap(Int224.unwrap(x) | Int224.unwrap(y)); }\nfunction bitorInt232(Int232 x, Int232 y) pure returns (Int232) { return Int232.wrap(Int232.unwrap(x) | Int232.unwrap(y)); }\nfunction bitorInt240(Int240 x, Int240 y) pure returns (Int240) { return Int240.wrap(Int240.unwrap(x) | Int240.unwrap(y)); }\nfunction bitorInt248(Int248 x, Int248 y) pure returns (Int248) { return Int248.wrap(Int248.unwrap(x) | Int248.unwrap(y)); }\nfunction bitorInt256(Int256 x, Int256 y) pure returns (Int256) { return Int256.wrap(Int256.unwrap(x) | Int256.unwrap(y)); }\nfunction bitorInt(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\n\nfunction unsubInt8(Int8 x) pure returns (Int8) { return Int8.wrap(-Int8.unwrap(x)); }\nfunction unsubInt16(Int16 x) pure returns (Int16) { return Int16.wrap(-Int16.unwrap(x)); }\nfunction unsubInt24(Int24 x) pure returns (Int24) { return Int24.wrap(-Int24.unwrap(x)); }\nfunction unsubInt32(Int32 x) pure returns (Int32) { return Int32.wrap(-Int32.unwrap(x)); }\nfunction unsubInt40(Int40 x) pure returns (Int40) { return Int40.wrap(-Int40.unwrap(x)); }\nfunction unsubInt48(Int48 x) pure returns (Int48) { return Int48.wrap(-Int48.unwrap(x)); }\nfunction unsubInt56(Int56 x) pure returns (Int56) { return Int56.wrap(-Int56.unwrap(x)); }\nfunction unsubInt64(Int64 x) pure returns (Int64) { return Int64.wrap(-Int64.unwrap(x)); }\nfunction unsubInt72(Int72 x) pure returns (Int72) { return Int72.wrap(-Int72.unwrap(x)); }\nfunction unsubInt80(Int80 x) pure returns (Int80) { return Int80.wrap(-Int80.unwrap(x)); }\nfunction unsubInt88(Int88 x) pure returns (Int88) { return Int88.wrap(-Int88.unwrap(x)); }\nfunction unsubInt96(Int96 x) pure returns (Int96) { return Int96.wrap(-Int96.unwrap(x)); }\nfunction unsubInt104(Int104 x) pure returns (Int104) { return Int104.wrap(-Int104.unwrap(x)); }\nfunction unsubInt112(Int112 x) pure returns (Int112) { return Int112.wrap(-Int112.unwrap(x)); }\nfunction unsubInt120(Int120 x) pure returns (Int120) { return Int120.wrap(-Int120.unwrap(x)); }\nfunction unsubInt128(Int128 x) pure returns (Int128) { return Int128.wrap(-Int128.unwrap(x)); }\nfunction unsubInt136(Int136 x) pure returns (Int136) { return Int136.wrap(-Int136.unwrap(x)); }\nfunction unsubInt144(Int144 x) pure returns (Int144) { return Int144.wrap(-Int144.unwrap(x)); }\nfunction unsubInt152(Int152 x) pure returns (Int152) { return Int152.wrap(-Int152.unwrap(x)); }\nfunction unsubInt160(Int160 x) pure returns (Int160) { return Int160.wrap(-Int160.unwrap(x)); }\nfunction unsubInt168(Int168 x) pure returns (Int168) { return Int168.wrap(-Int168.unwrap(x)); }\nfunction unsubInt176(Int176 x) pure returns (Int176) { return Int176.wrap(-Int176.unwrap(x)); }\nfunction unsubInt184(Int184 x) pure returns (Int184) { return Int184.wrap(-Int184.unwrap(x)); }\nfunction unsubInt192(Int192 x) pure returns (Int192) { return Int192.wrap(-Int192.unwrap(x)); }\nfunction unsubInt200(Int200 x) pure returns (Int200) { return Int200.wrap(-Int200.unwrap(x)); }\nfunction unsubInt208(Int208 x) pure returns (Int208) { return Int208.wrap(-Int208.unwrap(x)); }\nfunction unsubInt216(Int216 x) pure returns (Int216) { return Int216.wrap(-Int216.unwrap(x)); }\nfunction unsubInt224(Int224 x) pure returns (Int224) { return Int224.wrap(-Int224.unwrap(x)); }\nfunction unsubInt232(Int232 x) pure returns (Int232) { return Int232.wrap(-Int232.unwrap(x)); }\nfunction unsubInt240(Int240 x) pure returns (Int240) { return Int240.wrap(-Int240.unwrap(x)); }\nfunction unsubInt248(Int248 x) pure returns (Int248) { return Int248.wrap(-Int248.unwrap(x)); }\nfunction unsubInt256(Int256 x) pure returns (Int256) { return Int256.wrap(-Int256.unwrap(x)); }\nfunction unsubInt(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\n\nfunction bitorUint8(Uint8 x, Uint8 y) pure returns (Uint8) { return Uint8.wrap(Uint8.unwrap(x) | Uint8.unwrap(y)); }\nfunction bitorUint16(Uint16 x, Uint16 y) pure returns (Uint16) { return Uint16.wrap(Uint16.unwrap(x) | Uint16.unwrap(y)); }\nfunction bitorUint24(Uint24 x, Uint24 y) pure returns (Uint24) { return Uint24.wrap(Uint24.unwrap(x) | Uint24.unwrap(y)); }\nfunction bitorUint32(Uint32 x, Uint32 y) pure returns (Uint32) { return Uint32.wrap(Uint32.unwrap(x) | Uint32.unwrap(y)); }\nfunction bitorUint40(Uint40 x, Uint40 y) pure returns (Uint40) { return Uint40.wrap(Uint40.unwrap(x) | Uint40.unwrap(y)); }\nfunction bitorUint48(Uint48 x, Uint48 y) pure returns (Uint48) { return Uint48.wrap(Uint48.unwrap(x) | Uint48.unwrap(y)); }\nfunction bitorUint56(Uint56 x, Uint56 y) pure returns (Uint56) { return Uint56.wrap(Uint56.unwrap(x) | Uint56.unwrap(y)); }\nfunction bitorUint64(Uint64 x, Uint64 y) pure returns (Uint64) { return Uint64.wrap(Uint64.unwrap(x) | Uint64.unwrap(y)); }\nfunction bitorUint72(Uint72 x, Uint72 y) pure returns (Uint72) { return Uint72.wrap(Uint72.unwrap(x) | Uint72.unwrap(y)); }\nfunction bitorUint80(Uint80 x, Uint80 y) pure returns (Uint80) { return Uint80.wrap(Uint80.unwrap(x) | Uint80.unwrap(y)); }\nfunction bitorUint88(Uint88 x, Uint88 y) pure returns (Uint88) { return Uint88.wrap(Uint88.unwrap(x) | Uint88.unwrap(y)); }\nfunction bitorUint96(Uint96 x, Uint96 y) pure returns (Uint96) { return Uint96.wrap(Uint96.unwrap(x) | Uint96.unwrap(y)); }\nfunction bitorUint104(Uint104 x, Uint104 y) pure returns (Uint104) { return Uint104.wrap(Uint104.unwrap(x) | Uint104.unwrap(y)); }\nfunction bitorUint112(Uint112 x, Uint112 y) pure returns (Uint112) { return Uint112.wrap(Uint112.unwrap(x) | Uint112.unwrap(y)); }\nfunction bitorUint120(Uint120 x, Uint120 y) pure returns (Uint120) { return Uint120.wrap(Uint120.unwrap(x) | Uint120.unwrap(y)); }\nfunction bitorUint128(Uint128 x, Uint128 y) pure returns (Uint128) { return Uint128.wrap(Uint128.unwrap(x) | Uint128.unwrap(y)); }\nfunction bitorUint136(Uint136 x, Uint136 y) pure returns (Uint136) { return Uint136.wrap(Uint136.unwrap(x) | Uint136.unwrap(y)); }\nfunction bitorUint144(Uint144 x, Uint144 y) pure returns (Uint144) { return Uint144.wrap(Uint144.unwrap(x) | Uint144.unwrap(y)); }\nfunction bitorUint152(Uint152 x, Uint152 y) pure returns (Uint152) { return Uint152.wrap(Uint152.unwrap(x) | Uint152.unwrap(y)); }\nfunction bitorUint160(Uint160 x, Uint160 y) pure returns (Uint160) { return Uint160.wrap(Uint160.unwrap(x) | Uint160.unwrap(y)); }\nfunction bitorUint168(Uint168 x, Uint168 y) pure returns (Uint168) { return Uint168.wrap(Uint168.unwrap(x) | Uint168.unwrap(y)); }\nfunction bitorUint176(Uint176 x, Uint176 y) pure returns (Uint176) { return Uint176.wrap(Uint176.unwrap(x) | Uint176.unwrap(y)); }\nfunction bitorUint184(Uint184 x, Uint184 y) pure returns (Uint184) { return Uint184.wrap(Uint184.unwrap(x) | Uint184.unwrap(y)); }\nfunction bitorUint192(Uint192 x, Uint192 y) pure returns (Uint192) { return Uint192.wrap(Uint192.unwrap(x) | Uint192.unwrap(y)); }\nfunction bitorUint200(Uint200 x, Uint200 y) pure returns (Uint200) { return Uint200.wrap(Uint200.unwrap(x) | Uint200.unwrap(y)); }\nfunction bitorUint208(Uint208 x, Uint208 y) pure returns (Uint208) { return Uint208.wrap(Uint208.unwrap(x) | Uint208.unwrap(y)); }\nfunction bitorUint216(Uint216 x, Uint216 y) pure returns (Uint216) { return Uint216.wrap(Uint216.unwrap(x) | Uint216.unwrap(y)); }\nfunction bitorUint224(Uint224 x, Uint224 y) pure returns (Uint224) { return Uint224.wrap(Uint224.unwrap(x) | Uint224.unwrap(y)); }\nfunction bitorUint232(Uint232 x, Uint232 y) pure returns (Uint232) { return Uint232.wrap(Uint232.unwrap(x) | Uint232.unwrap(y)); }\nfunction bitorUint240(Uint240 x, Uint240 y) pure returns (Uint240) { return Uint240.wrap(Uint240.unwrap(x) | Uint240.unwrap(y)); }\nfunction bitorUint248(Uint248 x, Uint248 y) pure returns (Uint248) { return Uint248.wrap(Uint248.unwrap(x) | Uint248.unwrap(y)); }\nfunction bitorUint256(Uint256 x, Uint256 y) pure returns (Uint256) { return Uint256.wrap(Uint256.unwrap(x) | Uint256.unwrap(y)); }\nfunction bitorUint(Uint x, Uint y) pure returns (Uint) { return Uint.wrap(Uint.unwrap(x) | Uint.unwrap(y)); }\n\nfunction bitnotUint8(Uint8 x) pure returns (Uint8) { return Uint8.wrap(~Uint8.unwrap(x)); }\nfunction bitnotUint16(Uint16 x) pure returns (Uint16) { return Uint16.wrap(~Uint16.unwrap(x)); }\nfunction bitnotUint24(Uint24 x) pure returns (Uint24) { return Uint24.wrap(~Uint24.unwrap(x)); }\nfunction bitnotUint32(Uint32 x) pure returns (Uint32) { return Uint32.wrap(~Uint32.unwrap(x)); }\nfunction bitnotUint40(Uint40 x) pure returns (Uint40) { return Uint40.wrap(~Uint40.unwrap(x)); }\nfunction bitnotUint48(Uint48 x) pure returns (Uint48) { return Uint48.wrap(~Uint48.unwrap(x)); }\nfunction bitnotUint56(Uint56 x) pure returns (Uint56) { return Uint56.wrap(~Uint56.unwrap(x)); }\nfunction bitnotUint64(Uint64 x) pure returns (Uint64) { return Uint64.wrap(~Uint64.unwrap(x)); }\nfunction bitnotUint72(Uint72 x) pure returns (Uint72) { return Uint72.wrap(~Uint72.unwrap(x)); }\nfunction bitnotUint80(Uint80 x) pure returns (Uint80) { return Uint80.wrap(~Uint80.unwrap(x)); }\nfunction bitnotUint88(Uint88 x) pure returns (Uint88) { return Uint88.wrap(~Uint88.unwrap(x)); }\nfunction bitnotUint96(Uint96 x) pure returns (Uint96) { return Uint96.wrap(~Uint96.unwrap(x)); }\nfunction bitnotUint104(Uint104 x) pure returns (Uint104) { return Uint104.wrap(~Uint104.unwrap(x)); }\nfunction bitnotUint112(Uint112 x) pure returns (Uint112) { return Uint112.wrap(~Uint112.unwrap(x)); }\nfunction bitnotUint120(Uint120 x) pure returns (Uint120) { return Uint120.wrap(~Uint120.unwrap(x)); }\nfunction bitnotUint128(Uint128 x) pure returns (Uint128) { return Uint128.wrap(~Uint128.unwrap(x)); }\nfunction bitnotUint136(Uint136 x) pure returns (Uint136) { return Uint136.wrap(~Uint136.unwrap(x)); }\nfunction bitnotUint144(Uint144 x) pure returns (Uint144) { return Uint144.wrap(~Uint144.unwrap(x)); }\nfunction bitnotUint152(Uint152 x) pure returns (Uint152) { return Uint152.wrap(~Uint152.unwrap(x)); }\nfunction bitnotUint160(Uint160 x) pure returns (Uint160) { return Uint160.wrap(~Uint160.unwrap(x)); }\nfunction bitnotUint168(Uint168 x) pure returns (Uint168) { return Uint168.wrap(~Uint168.unwrap(x)); }\nfunction bitnotUint176(Uint176 x) pure returns (Uint176) { return Uint176.wrap(~Uint176.unwrap(x)); }\nfunction bitnotUint184(Uint184 x) pure returns (Uint184) { return Uint184.wrap(~Uint184.unwrap(x)); }\nfunction bitnotUint192(Uint192 x) pure returns (Uint192) { return Uint192.wrap(~Uint192.unwrap(x)); }\nfunction bitnotUint200(Uint200 x) pure returns (Uint200) { return Uint200.wrap(~Uint200.unwrap(x)); }\nfunction bitnotUint208(Uint208 x) pure returns (Uint208) { return Uint208.wrap(~Uint208.unwrap(x)); }\nfunction bitnotUint216(Uint216 x) pure returns (Uint216) { return Uint216.wrap(~Uint216.unwrap(x)); }\nfunction bitnotUint224(Uint224 x) pure returns (Uint224) { return Uint224.wrap(~Uint224.unwrap(x)); }\nfunction bitnotUint232(Uint232 x) pure returns (Uint232) { return Uint232.wrap(~Uint232.unwrap(x)); }\nfunction bitnotUint240(Uint240 x) pure returns (Uint240) { return Uint240.wrap(~Uint240.unwrap(x)); }\nfunction bitnotUint248(Uint248 x) pure returns (Uint248) { return Uint248.wrap(~Uint248.unwrap(x)); }\nfunction bitnotUint256(Uint256 x) pure returns (Uint256) { return Uint256.wrap(~Uint256.unwrap(x)); }\nfunction bitnotUint(Uint x) pure returns (Uint) { return Uint.wrap(~Uint.unwrap(x)); }\n\nfunction bitorBytes1(Bytes1 x, Bytes1 y) pure returns (Bytes1) { return Bytes1.wrap(Bytes1.unwrap(x) | Bytes1.unwrap(y)); }\nfunction bitorBytes2(Bytes2 x, Bytes2 y) pure returns (Bytes2) { return Bytes2.wrap(Bytes2.unwrap(x) | Bytes2.unwrap(y)); }\nfunction bitorBytes3(Bytes3 x, Bytes3 y) pure returns (Bytes3) { return Bytes3.wrap(Bytes3.unwrap(x) | Bytes3.unwrap(y)); }\nfunction bitorBytes4(Bytes4 x, Bytes4 y) pure returns (Bytes4) { return Bytes4.wrap(Bytes4.unwrap(x) | Bytes4.unwrap(y)); }\nfunction bitorBytes5(Bytes5 x, Bytes5 y) pure returns (Bytes5) { return Bytes5.wrap(Bytes5.unwrap(x) | Bytes5.unwrap(y)); }\nfunction bitorBytes6(Bytes6 x, Bytes6 y) pure returns (Bytes6) { return Bytes6.wrap(Bytes6.unwrap(x) | Bytes6.unwrap(y)); }\nfunction bitorBytes7(Bytes7 x, Bytes7 y) pure returns (Bytes7) { return Bytes7.wrap(Bytes7.unwrap(x) | Bytes7.unwrap(y)); }\nfunction bitorBytes8(Bytes8 x, Bytes8 y) pure returns (Bytes8) { return Bytes8.wrap(Bytes8.unwrap(x) | Bytes8.unwrap(y)); }\nfunction bitorBytes9(Bytes9 x, Bytes9 y) pure returns (Bytes9) { return Bytes9.wrap(Bytes9.unwrap(x) | Bytes9.unwrap(y)); }\nfunction bitorBytes10(Bytes10 x, Bytes10 y) pure returns (Bytes10) { return Bytes10.wrap(Bytes10.unwrap(x) | Bytes10.unwrap(y)); }\nfunction bitorBytes11(Bytes11 x, Bytes11 y) pure returns (Bytes11) { return Bytes11.wrap(Bytes11.unwrap(x) | Bytes11.unwrap(y)); }\nfunction bitorBytes12(Bytes12 x, Bytes12 y) pure returns (Bytes12) { return Bytes12.wrap(Bytes12.unwrap(x) | Bytes12.unwrap(y)); }\nfunction bitorBytes13(Bytes13 x, Bytes13 y) pure returns (Bytes13) { return Bytes13.wrap(Bytes13.unwrap(x) | Bytes13.unwrap(y)); }\nfunction bitorBytes14(Bytes14 x, Bytes14 y) pure returns (Bytes14) { return Bytes14.wrap(Bytes14.unwrap(x) | Bytes14.unwrap(y)); }\nfunction bitorBytes15(Bytes15 x, Bytes15 y) pure returns (Bytes15) { return Bytes15.wrap(Bytes15.unwrap(x) | Bytes15.unwrap(y)); }\nfunction bitorBytes16(Bytes16 x, Bytes16 y) pure returns (Bytes16) { return Bytes16.wrap(Bytes16.unwrap(x) | Bytes16.unwrap(y)); }\nfunction bitorBytes17(Bytes17 x, Bytes17 y) pure returns (Bytes17) { return Bytes17.wrap(Bytes17.unwrap(x) | Bytes17.unwrap(y)); }\nfunction bitorBytes18(Bytes18 x, Bytes18 y) pure returns (Bytes18) { return Bytes18.wrap(Bytes18.unwrap(x) | Bytes18.unwrap(y)); }\nfunction bitorBytes19(Bytes19 x, Bytes19 y) pure returns (Bytes19) { return Bytes19.wrap(Bytes19.unwrap(x) | Bytes19.unwrap(y)); }\nfunction bitorBytes20(Bytes20 x, Bytes20 y) pure returns (Bytes20) { return Bytes20.wrap(Bytes20.unwrap(x) | Bytes20.unwrap(y)); }\nfunction bitorBytes21(Bytes21 x, Bytes21 y) pure returns (Bytes21) { return Bytes21.wrap(Bytes21.unwrap(x) | Bytes21.unwrap(y)); }\nfunction bitorBytes22(Bytes22 x, Bytes22 y) pure returns (Bytes22) { return Bytes22.wrap(Bytes22.unwrap(x) | Bytes22.unwrap(y)); }\nfunction bitorBytes23(Bytes23 x, Bytes23 y) pure returns (Bytes23) { return Bytes23.wrap(Bytes23.unwrap(x) | Bytes23.unwrap(y)); }\nfunction bitorBytes24(Bytes24 x, Bytes24 y) pure returns (Bytes24) { return Bytes24.wrap(Bytes24.unwrap(x) | Bytes24.unwrap(y)); }\nfunction bitorBytes25(Bytes25 x, Bytes25 y) pure returns (Bytes25) { return Bytes25.wrap(Bytes25.unwrap(x) | Bytes25.unwrap(y)); }\nfunction bitorBytes26(Bytes26 x, Bytes26 y) pure returns (Bytes26) { return Bytes26.wrap(Bytes26.unwrap(x) | Bytes26.unwrap(y)); }\nfunction bitorBytes27(Bytes27 x, Bytes27 y) pure returns (Bytes27) { return Bytes27.wrap(Bytes27.unwrap(x) | Bytes27.unwrap(y)); }\nfunction bitorBytes28(Bytes28 x, Bytes28 y) pure returns (Bytes28) { return Bytes28.wrap(Bytes28.unwrap(x) | Bytes28.unwrap(y)); }\nfunction bitorBytes29(Bytes29 x, Bytes29 y) pure returns (Bytes29) { return Bytes29.wrap(Bytes29.unwrap(x) | Bytes29.unwrap(y)); }\nfunction bitorBytes30(Bytes30 x, Bytes30 y) pure returns (Bytes30) { return Bytes30.wrap(Bytes30.unwrap(x) | Bytes30.unwrap(y)); }\nfunction bitorBytes31(Bytes31 x, Bytes31 y) pure returns (Bytes31) { return Bytes31.wrap(Bytes31.unwrap(x) | Bytes31.unwrap(y)); }\nfunction bitorBytes32(Bytes32 x, Bytes32 y) pure returns (Bytes32) { return Bytes32.wrap(Bytes32.unwrap(x) | Bytes32.unwrap(y)); }\n\nfunction bitnotBytes1(Bytes1 x) pure returns (Bytes1) { return Bytes1.wrap(~Bytes1.unwrap(x)); }\nfunction bitnotBytes2(Bytes2 x) pure returns (Bytes2) { return Bytes2.wrap(~Bytes2.unwrap(x)); }\nfunction bitnotBytes3(Bytes3 x) pure returns (Bytes3) { return Bytes3.wrap(~Bytes3.unwrap(x)); }\nfunction bitnotBytes4(Bytes4 x) pure returns (Bytes4) { return Bytes4.wrap(~Bytes4.unwrap(x)); }\nfunction bitnotBytes5(Bytes5 x) pure returns (Bytes5) { return Bytes5.wrap(~Bytes5.unwrap(x)); }\nfunction bitnotBytes6(Bytes6 x) pure returns (Bytes6) { return Bytes6.wrap(~Bytes6.unwrap(x)); }\nfunction bitnotBytes7(Bytes7 x) pure returns (Bytes7) { return Bytes7.wrap(~Bytes7.unwrap(x)); }\nfunction bitnotBytes8(Bytes8 x) pure returns (Bytes8) { return Bytes8.wrap(~Bytes8.unwrap(x)); }\nfunction bitnotBytes9(Bytes9 x) pure returns (Bytes9) { return Bytes9.wrap(~Bytes9.unwrap(x)); }\nfunction bitnotBytes10(Bytes10 x) pure returns (Bytes10) { return Bytes10.wrap(~Bytes10.unwrap(x)); }\nfunction bitnotBytes11(Bytes11 x) pure returns (Bytes11) { return Bytes11.wrap(~Bytes11.unwrap(x)); }\nfunction bitnotBytes12(Bytes12 x) pure returns (Bytes12) { return Bytes12.wrap(~Bytes12.unwrap(x)); }\nfunction bitnotBytes13(Bytes13 x) pure returns (Bytes13) { return Bytes13.wrap(~Bytes13.unwrap(x)); }\nfunction bitnotBytes14(Bytes14 x) pure returns (Bytes14) { return Bytes14.wrap(~Bytes14.unwrap(x)); }\nfunction bitnotBytes15(Bytes15 x) pure returns (Bytes15) { return Bytes15.wrap(~Bytes15.unwrap(x)); }\nfunction bitnotBytes16(Bytes16 x) pure returns (Bytes16) { return Bytes16.wrap(~Bytes16.unwrap(x)); }\nfunction bitnotBytes17(Bytes17 x) pure returns (Bytes17) { return Bytes17.wrap(~Bytes17.unwrap(x)); }\nfunction bitnotBytes18(Bytes18 x) pure returns (Bytes18) { return Bytes18.wrap(~Bytes18.unwrap(x)); }\nfunction bitnotBytes19(Bytes19 x) pure returns (Bytes19) { return Bytes19.wrap(~Bytes19.unwrap(x)); }\nfunction bitnotBytes20(Bytes20 x) pure returns (Bytes20) { return Bytes20.wrap(~Bytes20.unwrap(x)); }\nfunction bitnotBytes21(Bytes21 x) pure returns (Bytes21) { return Bytes21.wrap(~Bytes21.unwrap(x)); }\nfunction bitnotBytes22(Bytes22 x) pure returns (Bytes22) { return Bytes22.wrap(~Bytes22.unwrap(x)); }\nfunction bitnotBytes23(Bytes23 x) pure returns (Bytes23) { return Bytes23.wrap(~Bytes23.unwrap(x)); }\nfunction bitnotBytes24(Bytes24 x) pure returns (Bytes24) { return Bytes24.wrap(~Bytes24.unwrap(x)); }\nfunction bitnotBytes25(Bytes25 x) pure returns (Bytes25) { return Bytes25.wrap(~Bytes25.unwrap(x)); }\nfunction bitnotBytes26(Bytes26 x) pure returns (Bytes26) { return Bytes26.wrap(~Bytes26.unwrap(x)); }\nfunction bitnotBytes27(Bytes27 x) pure returns (Bytes27) { return Bytes27.wrap(~Bytes27.unwrap(x)); }\nfunction bitnotBytes28(Bytes28 x) pure returns (Bytes28) { return Bytes28.wrap(~Bytes28.unwrap(x)); }\nfunction bitnotBytes29(Bytes29 x) pure returns (Bytes29) { return Bytes29.wrap(~Bytes29.unwrap(x)); }\nfunction bitnotBytes30(Bytes30 x) pure returns (Bytes30) { return Bytes30.wrap(~Bytes30.unwrap(x)); }\nfunction bitnotBytes31(Bytes31 x) pure returns (Bytes31) { return Bytes31.wrap(~Bytes31.unwrap(x)); }\nfunction bitnotBytes32(Bytes32 x) pure returns (Bytes32) { return Bytes32.wrap(~Bytes32.unwrap(x)); }\n\nusing {bitorAddress as |, bitnotAddress as ~} for Address global;\nusing {bitorAddressPayable as |, bitnotAddressPayable as ~} for AddressPayable global;\nusing {bitorBool as |, bitnotBool as ~} for Bool global;\n\nfunction bitorAddress(Address x, Address y) pure returns (Address) {\n return Address.wrap(address(bytes20(Address.unwrap(x)) | bytes20(Address.unwrap(y))));\n}\nfunction bitnotAddress(Address x) pure returns (Address) {\n return Address.wrap(address(~bytes20(Address.unwrap(x))));\n}\n\nfunction bitorAddressPayable(AddressPayable x, AddressPayable y) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(bytes20(address(AddressPayable.unwrap(x))) | bytes20(address(AddressPayable.unwrap(y))))));\n}\nfunction bitnotAddressPayable(AddressPayable x) pure returns (AddressPayable) {\n return AddressPayable.wrap(payable(address(~bytes20(address(AddressPayable.unwrap(x))))));\n}\n\nfunction bitorBool(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\nfunction bitnotBool(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n function testIntBinary() public pure {\n assert(Int8.unwrap(Int8.wrap(1) | Int8.wrap(2)) == 3);\n assert(Int16.unwrap(Int16.wrap(1) | Int16.wrap(2)) == 3);\n assert(Int24.unwrap(Int24.wrap(1) | Int24.wrap(2)) == 3);\n assert(Int32.unwrap(Int32.wrap(1) | Int32.wrap(2)) == 3);\n assert(Int40.unwrap(Int40.wrap(1) | Int40.wrap(2)) == 3);\n assert(Int48.unwrap(Int48.wrap(1) | Int48.wrap(2)) == 3);\n assert(Int56.unwrap(Int56.wrap(1) | Int56.wrap(2)) == 3);\n assert(Int64.unwrap(Int64.wrap(1) | Int64.wrap(2)) == 3);\n assert(Int72.unwrap(Int72.wrap(1) | Int72.wrap(2)) == 3);\n assert(Int80.unwrap(Int80.wrap(1) | Int80.wrap(2)) == 3);\n assert(Int88.unwrap(Int88.wrap(1) | Int88.wrap(2)) == 3);\n assert(Int96.unwrap(Int96.wrap(1) | Int96.wrap(2)) == 3);\n assert(Int104.unwrap(Int104.wrap(1) | Int104.wrap(2)) == 3);\n assert(Int112.unwrap(Int112.wrap(1) | Int112.wrap(2)) == 3);\n assert(Int120.unwrap(Int120.wrap(1) | Int120.wrap(2)) == 3);\n assert(Int128.unwrap(Int128.wrap(1) | Int128.wrap(2)) == 3);\n assert(Int136.unwrap(Int136.wrap(1) | Int136.wrap(2)) == 3);\n assert(Int144.unwrap(Int144.wrap(1) | Int144.wrap(2)) == 3);\n assert(Int152.unwrap(Int152.wrap(1) | Int152.wrap(2)) == 3);\n assert(Int160.unwrap(Int160.wrap(1) | Int160.wrap(2)) == 3);\n assert(Int168.unwrap(Int168.wrap(1) | Int168.wrap(2)) == 3);\n assert(Int176.unwrap(Int176.wrap(1) | Int176.wrap(2)) == 3);\n assert(Int184.unwrap(Int184.wrap(1) | Int184.wrap(2)) == 3);\n assert(Int192.unwrap(Int192.wrap(1) | Int192.wrap(2)) == 3);\n assert(Int200.unwrap(Int200.wrap(1) | Int200.wrap(2)) == 3);\n assert(Int208.unwrap(Int208.wrap(1) | Int208.wrap(2)) == 3);\n assert(Int216.unwrap(Int216.wrap(1) | Int216.wrap(2)) == 3);\n assert(Int224.unwrap(Int224.wrap(1) | Int224.wrap(2)) == 3);\n assert(Int232.unwrap(Int232.wrap(1) | Int232.wrap(2)) == 3);\n assert(Int240.unwrap(Int240.wrap(1) | Int240.wrap(2)) == 3);\n assert(Int248.unwrap(Int248.wrap(1) | Int248.wrap(2)) == 3);\n assert(Int256.unwrap(Int256.wrap(1) | Int256.wrap(2)) == 3);\n assert(Int.unwrap(Int.wrap(1) | Int.wrap(2)) == 3);\n }\n\n function testIntUnary() public pure {\n assert(Int8.unwrap(-Int8.wrap(1)) == -1);\n assert(Int16.unwrap(-Int16.wrap(1)) == -1);\n assert(Int24.unwrap(-Int24.wrap(1)) == -1);\n assert(Int32.unwrap(-Int32.wrap(1)) == -1);\n assert(Int40.unwrap(-Int40.wrap(1)) == -1);\n assert(Int48.unwrap(-Int48.wrap(1)) == -1);\n assert(Int56.unwrap(-Int56.wrap(1)) == -1);\n assert(Int64.unwrap(-Int64.wrap(1)) == -1);\n assert(Int72.unwrap(-Int72.wrap(1)) == -1);\n assert(Int80.unwrap(-Int80.wrap(1)) == -1);\n assert(Int88.unwrap(-Int88.wrap(1)) == -1);\n assert(Int96.unwrap(-Int96.wrap(1)) == -1);\n assert(Int104.unwrap(-Int104.wrap(1)) == -1);\n assert(Int112.unwrap(-Int112.wrap(1)) == -1);\n assert(Int120.unwrap(-Int120.wrap(1)) == -1);\n assert(Int128.unwrap(-Int128.wrap(1)) == -1);\n assert(Int136.unwrap(-Int136.wrap(1)) == -1);\n assert(Int144.unwrap(-Int144.wrap(1)) == -1);\n assert(Int152.unwrap(-Int152.wrap(1)) == -1);\n assert(Int160.unwrap(-Int160.wrap(1)) == -1);\n assert(Int168.unwrap(-Int168.wrap(1)) == -1);\n assert(Int176.unwrap(-Int176.wrap(1)) == -1);\n assert(Int184.unwrap(-Int184.wrap(1)) == -1);\n assert(Int192.unwrap(-Int192.wrap(1)) == -1);\n assert(Int200.unwrap(-Int200.wrap(1)) == -1);\n assert(Int208.unwrap(-Int208.wrap(1)) == -1);\n assert(Int216.unwrap(-Int216.wrap(1)) == -1);\n assert(Int224.unwrap(-Int224.wrap(1)) == -1);\n assert(Int232.unwrap(-Int232.wrap(1)) == -1);\n assert(Int240.unwrap(-Int240.wrap(1)) == -1);\n assert(Int248.unwrap(-Int248.wrap(1)) == -1);\n assert(Int256.unwrap(-Int256.wrap(1)) == -1);\n assert(Int.unwrap(-Int.wrap(1)) == -1);\n }\n\n function testUintBinary() public pure {\n assert(Uint8.unwrap(Uint8.wrap(1) | Uint8.wrap(2)) == 3);\n assert(Uint16.unwrap(Uint16.wrap(1) | Uint16.wrap(2)) == 3);\n assert(Uint24.unwrap(Uint24.wrap(1) | Uint24.wrap(2)) == 3);\n assert(Uint32.unwrap(Uint32.wrap(1) | Uint32.wrap(2)) == 3);\n assert(Uint40.unwrap(Uint40.wrap(1) | Uint40.wrap(2)) == 3);\n assert(Uint48.unwrap(Uint48.wrap(1) | Uint48.wrap(2)) == 3);\n assert(Uint56.unwrap(Uint56.wrap(1) | Uint56.wrap(2)) == 3);\n assert(Uint64.unwrap(Uint64.wrap(1) | Uint64.wrap(2)) == 3);\n assert(Uint72.unwrap(Uint72.wrap(1) | Uint72.wrap(2)) == 3);\n assert(Uint80.unwrap(Uint80.wrap(1) | Uint80.wrap(2)) == 3);\n assert(Uint88.unwrap(Uint88.wrap(1) | Uint88.wrap(2)) == 3);\n assert(Uint96.unwrap(Uint96.wrap(1) | Uint96.wrap(2)) == 3);\n assert(Uint104.unwrap(Uint104.wrap(1) | Uint104.wrap(2)) == 3);\n assert(Uint112.unwrap(Uint112.wrap(1) | Uint112.wrap(2)) == 3);\n assert(Uint120.unwrap(Uint120.wrap(1) | Uint120.wrap(2)) == 3);\n assert(Uint128.unwrap(Uint128.wrap(1) | Uint128.wrap(2)) == 3);\n assert(Uint136.unwrap(Uint136.wrap(1) | Uint136.wrap(2)) == 3);\n assert(Uint144.unwrap(Uint144.wrap(1) | Uint144.wrap(2)) == 3);\n assert(Uint152.unwrap(Uint152.wrap(1) | Uint152.wrap(2)) == 3);\n assert(Uint160.unwrap(Uint160.wrap(1) | Uint160.wrap(2)) == 3);\n assert(Uint168.unwrap(Uint168.wrap(1) | Uint168.wrap(2)) == 3);\n assert(Uint176.unwrap(Uint176.wrap(1) | Uint176.wrap(2)) == 3);\n assert(Uint184.unwrap(Uint184.wrap(1) | Uint184.wrap(2)) == 3);\n assert(Uint192.unwrap(Uint192.wrap(1) | Uint192.wrap(2)) == 3);\n assert(Uint200.unwrap(Uint200.wrap(1) | Uint200.wrap(2)) == 3);\n assert(Uint208.unwrap(Uint208.wrap(1) | Uint208.wrap(2)) == 3);\n assert(Uint216.unwrap(Uint216.wrap(1) | Uint216.wrap(2)) == 3);\n assert(Uint224.unwrap(Uint224.wrap(1) | Uint224.wrap(2)) == 3);\n assert(Uint232.unwrap(Uint232.wrap(1) | Uint232.wrap(2)) == 3);\n assert(Uint240.unwrap(Uint240.wrap(1) | Uint240.wrap(2)) == 3);\n assert(Uint248.unwrap(Uint248.wrap(1) | Uint248.wrap(2)) == 3);\n assert(Uint256.unwrap(Uint256.wrap(1) | Uint256.wrap(2)) == 3);\n assert(Uint.unwrap(Uint.wrap(1) | Uint.wrap(2)) == 3);\n }\n\n function testUintUnary() public pure {\n assert(Uint8.unwrap(~Uint8.wrap(1)) == ~uint8(1));\n assert(Uint16.unwrap(~Uint16.wrap(1)) == ~uint16(1));\n assert(Uint24.unwrap(~Uint24.wrap(1)) == ~uint24(1));\n assert(Uint32.unwrap(~Uint32.wrap(1)) == ~uint32(1));\n assert(Uint40.unwrap(~Uint40.wrap(1)) == ~uint40(1));\n assert(Uint48.unwrap(~Uint48.wrap(1)) == ~uint48(1));\n assert(Uint56.unwrap(~Uint56.wrap(1)) == ~uint56(1));\n assert(Uint64.unwrap(~Uint64.wrap(1)) == ~uint64(1));\n assert(Uint72.unwrap(~Uint72.wrap(1)) == ~uint72(1));\n assert(Uint80.unwrap(~Uint80.wrap(1)) == ~uint80(1));\n assert(Uint88.unwrap(~Uint88.wrap(1)) == ~uint88(1));\n assert(Uint96.unwrap(~Uint96.wrap(1)) == ~uint96(1));\n assert(Uint104.unwrap(~Uint104.wrap(1)) == ~uint104(1));\n assert(Uint112.unwrap(~Uint112.wrap(1)) == ~uint112(1));\n assert(Uint120.unwrap(~Uint120.wrap(1)) == ~uint120(1));\n assert(Uint128.unwrap(~Uint128.wrap(1)) == ~uint128(1));\n assert(Uint136.unwrap(~Uint136.wrap(1)) == ~uint136(1));\n assert(Uint144.unwrap(~Uint144.wrap(1)) == ~uint144(1));\n assert(Uint152.unwrap(~Uint152.wrap(1)) == ~uint152(1));\n assert(Uint160.unwrap(~Uint160.wrap(1)) == ~uint160(1));\n assert(Uint168.unwrap(~Uint168.wrap(1)) == ~uint168(1));\n assert(Uint176.unwrap(~Uint176.wrap(1)) == ~uint176(1));\n assert(Uint184.unwrap(~Uint184.wrap(1)) == ~uint184(1));\n assert(Uint192.unwrap(~Uint192.wrap(1)) == ~uint192(1));\n assert(Uint200.unwrap(~Uint200.wrap(1)) == ~uint200(1));\n assert(Uint208.unwrap(~Uint208.wrap(1)) == ~uint208(1));\n assert(Uint216.unwrap(~Uint216.wrap(1)) == ~uint216(1));\n assert(Uint224.unwrap(~Uint224.wrap(1)) == ~uint224(1));\n assert(Uint232.unwrap(~Uint232.wrap(1)) == ~uint232(1));\n assert(Uint240.unwrap(~Uint240.wrap(1)) == ~uint240(1));\n assert(Uint248.unwrap(~Uint248.wrap(1)) == ~uint248(1));\n assert(Uint256.unwrap(~Uint256.wrap(1)) == ~uint256(1));\n assert(Uint.unwrap(~Uint.wrap(1)) == ~uint(1));\n }\n\n function testBytesBinary() public pure {\n assert(Bytes1.unwrap(Bytes1.wrap(0x01) | Bytes1.wrap(0x02)) == bytes1(0x03));\n assert(Bytes2.unwrap(Bytes2.wrap(bytes2(bytes1(0x01))) | Bytes2.wrap(bytes2(bytes1(0x02)))) == bytes2(bytes1(0x03)));\n assert(Bytes3.unwrap(Bytes3.wrap(bytes3(bytes1(0x01))) | Bytes3.wrap(bytes3(bytes1(0x02)))) == bytes3(bytes1(0x03)));\n assert(Bytes4.unwrap(Bytes4.wrap(bytes4(bytes1(0x01))) | Bytes4.wrap(bytes4(bytes1(0x02)))) == bytes4(bytes1(0x03)));\n assert(Bytes5.unwrap(Bytes5.wrap(bytes5(bytes1(0x01))) | Bytes5.wrap(bytes5(bytes1(0x02)))) == bytes5(bytes1(0x03)));\n assert(Bytes6.unwrap(Bytes6.wrap(bytes6(bytes1(0x01))) | Bytes6.wrap(bytes6(bytes1(0x02)))) == bytes6(bytes1(0x03)));\n assert(Bytes7.unwrap(Bytes7.wrap(bytes7(bytes1(0x01))) | Bytes7.wrap(bytes7(bytes1(0x02)))) == bytes7(bytes1(0x03)));\n assert(Bytes8.unwrap(Bytes8.wrap(bytes8(bytes1(0x01))) | Bytes8.wrap(bytes8(bytes1(0x02)))) == bytes8(bytes1(0x03)));\n assert(Bytes9.unwrap(Bytes9.wrap(bytes9(bytes1(0x01))) | Bytes9.wrap(bytes9(bytes1(0x02)))) == bytes9(bytes1(0x03)));\n assert(Bytes10.unwrap(Bytes10.wrap(bytes10(bytes1(0x01))) | Bytes10.wrap(bytes10(bytes1(0x02)))) == bytes10(bytes1(0x03)));\n assert(Bytes11.unwrap(Bytes11.wrap(bytes11(bytes1(0x01))) | Bytes11.wrap(bytes11(bytes1(0x02)))) == bytes11(bytes1(0x03)));\n assert(Bytes12.unwrap(Bytes12.wrap(bytes12(bytes1(0x01))) | Bytes12.wrap(bytes12(bytes1(0x02)))) == bytes12(bytes1(0x03)));\n assert(Bytes13.unwrap(Bytes13.wrap(bytes13(bytes1(0x01))) | Bytes13.wrap(bytes13(bytes1(0x02)))) == bytes13(bytes1(0x03)));\n assert(Bytes14.unwrap(Bytes14.wrap(bytes14(bytes1(0x01))) | Bytes14.wrap(bytes14(bytes1(0x02)))) == bytes14(bytes1(0x03)));\n assert(Bytes15.unwrap(Bytes15.wrap(bytes15(bytes1(0x01))) | Bytes15.wrap(bytes15(bytes1(0x02)))) == bytes15(bytes1(0x03)));\n assert(Bytes16.unwrap(Bytes16.wrap(bytes16(bytes1(0x01))) | Bytes16.wrap(bytes16(bytes1(0x02)))) == bytes16(bytes1(0x03)));\n assert(Bytes17.unwrap(Bytes17.wrap(bytes17(bytes1(0x01))) | Bytes17.wrap(bytes17(bytes1(0x02)))) == bytes17(bytes1(0x03)));\n assert(Bytes18.unwrap(Bytes18.wrap(bytes18(bytes1(0x01))) | Bytes18.wrap(bytes18(bytes1(0x02)))) == bytes18(bytes1(0x03)));\n assert(Bytes19.unwrap(Bytes19.wrap(bytes19(bytes1(0x01))) | Bytes19.wrap(bytes19(bytes1(0x02)))) == bytes19(bytes1(0x03)));\n assert(Bytes20.unwrap(Bytes20.wrap(bytes20(bytes1(0x01))) | Bytes20.wrap(bytes20(bytes1(0x02)))) == bytes20(bytes1(0x03)));\n assert(Bytes21.unwrap(Bytes21.wrap(bytes21(bytes1(0x01))) | Bytes21.wrap(bytes21(bytes1(0x02)))) == bytes21(bytes1(0x03)));\n assert(Bytes22.unwrap(Bytes22.wrap(bytes22(bytes1(0x01))) | Bytes22.wrap(bytes22(bytes1(0x02)))) == bytes22(bytes1(0x03)));\n assert(Bytes23.unwrap(Bytes23.wrap(bytes23(bytes1(0x01))) | Bytes23.wrap(bytes23(bytes1(0x02)))) == bytes23(bytes1(0x03)));\n assert(Bytes24.unwrap(Bytes24.wrap(bytes24(bytes1(0x01))) | Bytes24.wrap(bytes24(bytes1(0x02)))) == bytes24(bytes1(0x03)));\n assert(Bytes25.unwrap(Bytes25.wrap(bytes25(bytes1(0x01))) | Bytes25.wrap(bytes25(bytes1(0x02)))) == bytes25(bytes1(0x03)));\n assert(Bytes26.unwrap(Bytes26.wrap(bytes26(bytes1(0x01))) | Bytes26.wrap(bytes26(bytes1(0x02)))) == bytes26(bytes1(0x03)));\n assert(Bytes27.unwrap(Bytes27.wrap(bytes27(bytes1(0x01))) | Bytes27.wrap(bytes27(bytes1(0x02)))) == bytes27(bytes1(0x03)));\n assert(Bytes28.unwrap(Bytes28.wrap(bytes28(bytes1(0x01))) | Bytes28.wrap(bytes28(bytes1(0x02)))) == bytes28(bytes1(0x03)));\n assert(Bytes29.unwrap(Bytes29.wrap(bytes29(bytes1(0x01))) | Bytes29.wrap(bytes29(bytes1(0x02)))) == bytes29(bytes1(0x03)));\n assert(Bytes30.unwrap(Bytes30.wrap(bytes30(bytes1(0x01))) | Bytes30.wrap(bytes30(bytes1(0x02)))) == bytes30(bytes1(0x03)));\n assert(Bytes31.unwrap(Bytes31.wrap(bytes31(bytes1(0x01))) | Bytes31.wrap(bytes31(bytes1(0x02)))) == bytes31(bytes1(0x03)));\n assert(Bytes32.unwrap(Bytes32.wrap(bytes32(bytes1(0x01))) | Bytes32.wrap(bytes32(bytes1(0x02)))) == bytes32(bytes1(0x03)));\n }\n\n function testBytesUnary() public pure {\n assert(Bytes1.unwrap(~Bytes1.wrap(bytes1(0x01))) == ~bytes1(0x01));\n assert(Bytes2.unwrap(~Bytes2.wrap(bytes2(bytes1(0x01)))) == ~bytes2(bytes1(0x01)));\n assert(Bytes3.unwrap(~Bytes3.wrap(bytes3(bytes1(0x01)))) == ~bytes3(bytes1(0x01)));\n assert(Bytes4.unwrap(~Bytes4.wrap(bytes4(bytes1(0x01)))) == ~bytes4(bytes1(0x01)));\n assert(Bytes5.unwrap(~Bytes5.wrap(bytes5(bytes1(0x01)))) == ~bytes5(bytes1(0x01)));\n assert(Bytes6.unwrap(~Bytes6.wrap(bytes6(bytes1(0x01)))) == ~bytes6(bytes1(0x01)));\n assert(Bytes7.unwrap(~Bytes7.wrap(bytes7(bytes1(0x01)))) == ~bytes7(bytes1(0x01)));\n assert(Bytes8.unwrap(~Bytes8.wrap(bytes8(bytes1(0x01)))) == ~bytes8(bytes1(0x01)));\n assert(Bytes9.unwrap(~Bytes9.wrap(bytes9(bytes1(0x01)))) == ~bytes9(bytes1(0x01)));\n assert(Bytes10.unwrap(~Bytes10.wrap(bytes10(bytes1(0x01)))) == ~bytes10(bytes1(0x01)));\n assert(Bytes11.unwrap(~Bytes11.wrap(bytes11(bytes1(0x01)))) == ~bytes11(bytes1(0x01)));\n assert(Bytes12.unwrap(~Bytes12.wrap(bytes12(bytes1(0x01)))) == ~bytes12(bytes1(0x01)));\n assert(Bytes13.unwrap(~Bytes13.wrap(bytes13(bytes1(0x01)))) == ~bytes13(bytes1(0x01)));\n assert(Bytes14.unwrap(~Bytes14.wrap(bytes14(bytes1(0x01)))) == ~bytes14(bytes1(0x01)));\n assert(Bytes15.unwrap(~Bytes15.wrap(bytes15(bytes1(0x01)))) == ~bytes15(bytes1(0x01)));\n assert(Bytes16.unwrap(~Bytes16.wrap(bytes16(bytes1(0x01)))) == ~bytes16(bytes1(0x01)));\n assert(Bytes17.unwrap(~Bytes17.wrap(bytes17(bytes1(0x01)))) == ~bytes17(bytes1(0x01)));\n assert(Bytes18.unwrap(~Bytes18.wrap(bytes18(bytes1(0x01)))) == ~bytes18(bytes1(0x01)));\n assert(Bytes19.unwrap(~Bytes19.wrap(bytes19(bytes1(0x01)))) == ~bytes19(bytes1(0x01)));\n assert(Bytes20.unwrap(~Bytes20.wrap(bytes20(bytes1(0x01)))) == ~bytes20(bytes1(0x01)));\n assert(Bytes21.unwrap(~Bytes21.wrap(bytes21(bytes1(0x01)))) == ~bytes21(bytes1(0x01)));\n assert(Bytes22.unwrap(~Bytes22.wrap(bytes22(bytes1(0x01)))) == ~bytes22(bytes1(0x01)));\n assert(Bytes23.unwrap(~Bytes23.wrap(bytes23(bytes1(0x01)))) == ~bytes23(bytes1(0x01)));\n assert(Bytes24.unwrap(~Bytes24.wrap(bytes24(bytes1(0x01)))) == ~bytes24(bytes1(0x01)));\n assert(Bytes25.unwrap(~Bytes25.wrap(bytes25(bytes1(0x01)))) == ~bytes25(bytes1(0x01)));\n assert(Bytes26.unwrap(~Bytes26.wrap(bytes26(bytes1(0x01)))) == ~bytes26(bytes1(0x01)));\n assert(Bytes27.unwrap(~Bytes27.wrap(bytes27(bytes1(0x01)))) == ~bytes27(bytes1(0x01)));\n assert(Bytes28.unwrap(~Bytes28.wrap(bytes28(bytes1(0x01)))) == ~bytes28(bytes1(0x01)));\n assert(Bytes29.unwrap(~Bytes29.wrap(bytes29(bytes1(0x01)))) == ~bytes29(bytes1(0x01)));\n assert(Bytes30.unwrap(~Bytes30.wrap(bytes30(bytes1(0x01)))) == ~bytes30(bytes1(0x01)));\n assert(Bytes31.unwrap(~Bytes31.wrap(bytes31(bytes1(0x01)))) == ~bytes31(bytes1(0x01)));\n assert(Bytes32.unwrap(~Bytes32.wrap(bytes32(bytes1(0x01)))) == ~bytes32(bytes1(0x01)));\n }\n\n function testOtherBinary() public pure {\n assert(Address.unwrap(Address.wrap(address(0x01)) | Address.wrap(address(0x02))) == address(0x03));\n assert(AddressPayable.unwrap(AddressPayable.wrap(payable(address(0x01))) | AddressPayable.wrap(payable(address(0x02)))) == payable(address(0x03)));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n\n function testOtherUnary() public pure {\n assert(Address.unwrap(~Address.wrap(address(0))) == address(~bytes20(0)));\n assert(AddressPayable.unwrap(~AddressPayable.wrap(payable(address(0)))) == payable(address(~bytes20(0))));\n assert(Bool.unwrap(~Bool.wrap(true)) == false);\n }\n}\n// ----\n// testIntBinary() ->\n// testIntUnary() ->\n// testUintBinary() ->\n// testUintUnary() ->\n// testBytesBinary() ->\n// testBytesUnary() ->\n// testOtherBinary() ->\n// testOtherUnary() ->\n" + }, + "operator_making_pure_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdder {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ncontract Adder is IAdder {\n function mul(Int32 x, Int32 y) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external pure override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdder adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdder adder) {\n assembly {\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "fixed_point_udvt_with_operators.sol": { + "content": "type Fixed is int128;\nusing {add as +, mul as *} for Fixed global;\n\nint constant MULTIPLIER = 10**18;\n\nfunction add(Fixed a, Fixed b) pure returns (Fixed) {\n return Fixed.wrap(Fixed.unwrap(a) + Fixed.unwrap(b));\n}\n\nfunction mul(Fixed a, Fixed b) pure returns (Fixed) {\n int intermediate = (int(Fixed.unwrap(a)) * int(Fixed.unwrap(b))) / MULTIPLIER;\n if (int128(intermediate) != intermediate) { revert(\"Overflow\"); }\n return Fixed.wrap(int128(intermediate));\n}\n\ncontract C {\n function applyInterest(Fixed value, Fixed percentage) public pure returns (Fixed result) {\n return value + value * percentage;\n }\n}\n// ----\n// applyInterest(int128,int128): 500000000000000000000, 100000000000000000 -> 550000000000000000000\n" + }, + "checked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction checkedAdd(U8 x, U8 y) pure returns (U8) {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n}\n\nusing {checkedAdd as +} for U8 global;\n\ncontract C {\n function testCheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testCheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testCheckedOperator() -> FAILURE, hex\"4e487b71\", 0x11\n// testCheckedOperatorInUncheckedBlock() -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "multiple_operator_definitions_same_type_same_function_same_directive.sol": { + "content": "type Int is int32;\n\nusing {foo as +, foo as -} for Int global;\n\nfunction foo(Int a, Int b) pure returns(Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function f() pure public returns (Int) {\n return Int.wrap(2) + Int.wrap(3);\n }\n\n function g() pure public returns (Int) {\n return Int.wrap(6) - Int.wrap(1);\n }\n}\n// ----\n// f() -> 5\n// g() -> 7\n" + }, + "multiple_operator_definitions_different_types_different_functions_separate_directives.sol": { + "content": "type SmallInt is int;\ntype BigInt is int;\n\nusing {addSmall as +} for SmallInt global;\nusing {addBig as +} for BigInt global;\n\nfunction addSmall(SmallInt a, SmallInt b) pure returns (SmallInt) {\n return SmallInt.wrap(SmallInt.unwrap(a) + SmallInt.unwrap(b));\n}\n\nfunction addBig(BigInt a, BigInt b) pure returns (BigInt) {\n return BigInt.wrap(10 * (BigInt.unwrap(a) + BigInt.unwrap(b)));\n}\n\ncontract C {\n function small() public pure returns (SmallInt) {\n return SmallInt.wrap(1) + SmallInt.wrap(2);\n }\n\n function big() public pure returns (BigInt) {\n return BigInt.wrap(3) + BigInt.wrap(4);\n }\n}\n// ----\n// small() -> 3\n// big() -> 70\n" + }, + "consecutive_operator_invocations.sol": { + "content": "type A is address;\n\nusing {add as +} for A global;\n\nfunction add(A a, A b) pure returns (A) {\n return A.wrap(address(uint160(A.unwrap(a)) + uint160(A.unwrap(b))));\n}\n\ncontract C {\n function g() public pure returns (A) {\n A a = A.wrap(0x3333333333333333333333333333333333333333);\n A b = A.wrap(0x1111111111111111111111111111111111111111);\n A c = A.wrap(0x5555555555555555555555555555555555555555);\n return a + b + c;\n }\n}\n// ----\n// g() -> 0x9999999999999999999999999999999999999999\n" + }, + "operator_evaluation_order.sol": { + "content": "type Bool is bool;\nusing {add as +, mul as *, unsub as -} for Bool global;\n\nfunction add(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) || Bool.unwrap(y));\n}\n\nfunction mul(Bool x, Bool y) pure returns (Bool) {\n return Bool.wrap(Bool.unwrap(x) && Bool.unwrap(y));\n}\n\nfunction unsub(Bool x) pure returns (Bool) {\n return Bool.wrap(!Bool.unwrap(x));\n}\n\ncontract C {\n event Wrapped(uint);\n event Probe(Bool);\n\n function toBool(uint x) public returns (Bool) {\n emit Wrapped(x);\n return Bool.wrap(x > 0);\n }\n\n function probe(Bool x) public returns (Bool) {\n emit Probe(x);\n return x;\n }\n\n function testSingleOperator() public {\n toBool(0) +\n (toBool(1) + toBool(2)) +\n toBool(3);\n }\n\n function testTwoBinaryOperators() public {\n toBool(0) * toBool(1) +\n (toBool(2) * toBool(3)) +\n toBool(4) * toBool(5);\n }\n\n function testBinaryAndUnaryOperators() public {\n -toBool(0) * -toBool(1) +\n (-toBool(2) * -toBool(3)) +\n -toBool(4) * -toBool(5);\n }\n\n function testOperatorsNestedInCalls() public {\n -probe(toBool(0) * -toBool(1)) +\n (-probe(toBool(2) * -toBool(3))) +\n -probe(toBool(4) * -toBool(5));\n }\n}\n// ----\n// testSingleOperator() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// testTwoBinaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testBinaryAndUnaryOperators() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// testOperatorsNestedInCalls() ->\n// ~ emit Wrapped(uint256): 0x00\n// ~ emit Wrapped(uint256): 0x01\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x02\n// ~ emit Wrapped(uint256): 0x03\n// ~ emit Probe(bool): 0x00\n// ~ emit Wrapped(uint256): 0x04\n// ~ emit Wrapped(uint256): 0x05\n// ~ emit Probe(bool): 0x00\n" + }, + "recursive_operator.sol": { + "content": "type Uint is uint;\nusing {unaryCountdown as ~, binaryCountdown as ^, eq as ==} for Uint global;\n\nfunction unaryCountdown(Uint x) pure returns (Uint) {\n if (x == Uint.wrap(0))\n return Uint.wrap(0);\n\n return ~Uint.wrap(Uint.unwrap(x) - 1);\n}\n\nfunction binaryCountdown(Uint x, Uint y) pure returns (Uint) {\n if (x == Uint.wrap(0) && y == Uint.wrap(0))\n return Uint.wrap(0);\n if (x == Uint.wrap(0))\n return y ^ x;\n\n return Uint.wrap(Uint.unwrap(x) - 1) ^ y;\n}\n\nfunction eq(Uint x, Uint y) pure returns (bool) {\n return Uint.unwrap(x) == Uint.unwrap(y);\n}\n\ncontract C {\n function testUnary(Uint x) public pure returns (Uint) {\n return ~x;\n }\n\n function testBinary(Uint x, Uint y) public pure returns (Uint) {\n return x ^ y;\n }\n}\n// ----\n// testUnary(uint256): 0 -> 0\n// testUnary(uint256): 1 -> 0\n// testUnary(uint256): 99999999999 -> FAILURE\n// testBinary(uint256,uint256): 0, 0 -> 0\n// testBinary(uint256,uint256): 1, 0 -> 0\n// testBinary(uint256,uint256): 0, 1 -> 0\n// testBinary(uint256,uint256): 1, 1 -> 0\n// testBinary(uint256,uint256): 99999999999, 99999999999 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators.sol b/examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators.sol new file mode 100644 index 00000000..9f3fd5d4 --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators.sol @@ -0,0 +1,24 @@ +type U8 is uint8; + +function uncheckedAdd(U8 x, U8 y) pure returns (U8) { + unchecked { + return U8.wrap(U8.unwrap(x) + U8.unwrap(y)); + } +} + +using {uncheckedAdd as +} for U8 global; + +contract D { + function testUncheckedOperator() public pure returns (U8) { + return U8.wrap(250) + U8.wrap(10); + } + + function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) { + unchecked { + return U8.wrap(250) + U8.wrap(10); + } + } +} +// ---- +// testUncheckedOperator() -> 4 +// testUncheckedOperatorInUncheckedBlock() -> 4 diff --git a/examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators_standard_input.json b/examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators_standard_input.json new file mode 100644 index 00000000..56ee816e --- /dev/null +++ b/examples/test/semanticTests/operators_userDefined_unchecked_operators/unchecked_operators_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "operator_definition_shadowing_builtin_keccak256.sol": { + "content": "type Int is int16;\n\nusing {keccak256 as +} for Int global;\n\nfunction keccak256(Int a, Int b) pure returns (Int) {\n return Int.wrap(Int.unwrap(a) + Int.unwrap(b));\n}\n\ncontract C {\n function test() public returns (Int) {\n return Int.wrap(3) + Int.wrap(4);\n }\n}\n// ----\n// test() -> 7\n" + }, + "all_possible_operators.sol": { + "content": "type Int is int8;\nusing {\n bitor as |, bitand as &, bitxor as ^, bitnot as ~,\n add as +, sub as -, unsub as -, mul as *, div as /, mod as %,\n eq as ==, noteq as !=, lt as <, gt as >, leq as <=, geq as >=\n} for Int global;\n\nfunction bitor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) | Int.unwrap(y)); }\nfunction bitand(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) & Int.unwrap(y)); }\nfunction bitxor(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) ^ Int.unwrap(y)); }\nfunction bitnot(Int x) pure returns (Int) { return Int.wrap(~Int.unwrap(x)); }\n\nfunction add(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) + Int.unwrap(y)); }\nfunction sub(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) - Int.unwrap(y)); }\nfunction unsub(Int x) pure returns (Int) { return Int.wrap(-Int.unwrap(x)); }\nfunction mul(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) * Int.unwrap(y)); }\nfunction div(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) / Int.unwrap(y)); }\nfunction mod(Int x, Int y) pure returns (Int) { return Int.wrap(Int.unwrap(x) % Int.unwrap(y)); }\n\nfunction eq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) == Int.unwrap(y); }\nfunction noteq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) != Int.unwrap(y); }\nfunction lt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) < Int.unwrap(y); }\nfunction gt(Int x, Int y) pure returns (bool) { return Int.unwrap(x) > Int.unwrap(y); }\nfunction leq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) <= Int.unwrap(y); }\nfunction geq(Int x, Int y) pure returns (bool) { return Int.unwrap(x) >= Int.unwrap(y); }\n\ncontract C {\n Int constant ZERO = Int.wrap(0);\n Int constant ONE = Int.wrap(1);\n Int constant TWO = Int.wrap(2);\n Int constant THREE = Int.wrap(3);\n Int constant SIX = Int.wrap(6);\n\n function testBitwise() public pure {\n assert(Int.unwrap(ONE | TWO) == 3);\n assert(Int.unwrap(ONE | ZERO) == 1);\n\n assert(Int.unwrap(ONE & THREE) == 1);\n assert(Int.unwrap(ONE & ONE) == 1);\n\n assert(Int.unwrap(TWO ^ TWO) == 0);\n assert(Int.unwrap(TWO ^ ONE) == 3);\n\n assert(Int.unwrap(~ZERO) == -1);\n assert(Int.unwrap(~ONE) == -2);\n assert(Int.unwrap(~TWO) == -3);\n }\n\n function testArithmetic() public pure {\n assert(Int.unwrap(ONE + TWO) == 3);\n assert(Int.unwrap(ONE + ZERO) == 1);\n\n assert(Int.unwrap(TWO - ONE) == 1);\n assert(Int.unwrap(THREE - THREE) == 0);\n\n assert(Int.unwrap(-TWO) == -2);\n assert(Int.unwrap(-ZERO) == 0);\n\n assert(Int.unwrap(ONE * ONE) == 1);\n assert(Int.unwrap(THREE * TWO) == 6);\n\n assert(Int.unwrap(SIX / TWO) == 3);\n assert(Int.unwrap(THREE / TWO) == 1);\n\n assert(Int.unwrap(SIX % TWO) == 0);\n assert(Int.unwrap(THREE % TWO) == 1);\n }\n\n function testComparison() public pure {\n assert((ONE == ONE) == true);\n assert((ONE == TWO) == false);\n\n assert((ONE != ONE) == false);\n assert((ONE != TWO) == true);\n\n assert((ONE < TWO) == true);\n assert((TWO < ONE) == false);\n\n assert((ONE <= TWO) == true);\n assert((TWO <= ONE) == false);\n\n assert((ONE > TWO) == false);\n assert((TWO > ONE) == true);\n\n assert((ONE >= TWO) == false);\n assert((TWO >= ONE) == true);\n }\n}\n// ----\n// testBitwise() ->\n// testArithmetic() ->\n// testComparison() ->\n" + }, + "operator_making_view_external_call.sol": { + "content": "type Int32 is int32;\nusing {add as +, unsub as -} for Int32 global;\n\nfunction add(Int32 x, Int32 y) pure returns (Int32) {\n return loadAdder().mul(x, y);\n}\n\nfunction unsub(Int32 x) pure returns (Int32) {\n return loadAdder().inc(x);\n}\n\ninterface IAdderPure {\n function mul(Int32, Int32) external pure returns (Int32);\n function inc(Int32) external pure returns (Int32);\n}\n\ninterface IAdderView {\n function mul(Int32, Int32) external view returns (Int32);\n function inc(Int32) external view returns (Int32);\n}\n\ncontract Adder is IAdderView {\n function mul(Int32 x, Int32 y) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) * Int32.unwrap(y));\n }\n\n function inc(Int32 x) external view override returns (Int32) {\n return Int32.wrap(Int32.unwrap(x) + 1);\n }\n}\n\nfunction storeAdder(IAdderView adder) pure {\n assembly {\n // This test would also work without assembly if we could hard-code an address here.\n mstore(0, adder)\n }\n}\n\nfunction loadAdder() pure returns (IAdderPure adder) {\n assembly {\n // The adder we stored is view but we cheat by using a modified version with pure functions\n adder := mload(0)\n }\n}\n\ncontract C {\n function testMul(Int32 x, Int32 y) public returns (Int32) {\n storeAdder(new Adder());\n\n return x + y;\n }\n\n function testInc(Int32 x) public returns (Int32) {\n storeAdder(new Adder());\n\n return -x;\n }\n}\n// ----\n// testMul(int32,int32): 42, 10 -> 420\n// gas irOptimized: 102563\n// gas legacy: 56978\n// gas legacy code: 127000\n// gas legacyOptimized: 55161\n// gas legacyOptimized code: 68400\n// testInc(int32): 42 -> 43\n// gas irOptimized: 102386\n// gas legacy: 56238\n// gas legacy code: 127000\n// gas legacyOptimized: 54851\n// gas legacyOptimized code: 68400\n" + }, + "operator_return_parameter_cleanup.sol": { + "content": "type U8 is uint8;\nusing {f as ~, g as +} for U8 global;\n\nfunction f(U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\nfunction g(U8, U8) pure returns (U8 z) {\n assembly {\n // Return a value with dirty bytes outside of uint8\n z := 0xffff\n }\n}\n\ncontract C {\n function testUnary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n\n U8 opResult = ~a;\n U8 fResult = f(a);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n\n function testBinary() external pure returns (uint, uint) {\n U8 a; // Value does not matter\n U8 b; // Value does not matter\n\n U8 opResult = a + b;\n U8 fResult = g(a, b);\n\n // Get the slot, including bytes outside of uint8\n uint opResultFull;\n uint fResultFull;\n assembly {\n opResultFull := opResult\n fResultFull := fResult\n }\n\n // If the result is not 0xff, no cleanup was performed.\n return (opResultFull, fResultFull);\n }\n}\n// ----\n// testUnary() -> 0xffff, 0xffff\n// testBinary() -> 0xffff, 0xffff\n" + }, + "unchecked_operators.sol": { + "content": "type U8 is uint8;\n\nfunction uncheckedAdd(U8 x, U8 y) pure returns (U8) {\n unchecked {\n return U8.wrap(U8.unwrap(x) + U8.unwrap(y));\n }\n}\n\nusing {uncheckedAdd as +} for U8 global;\n\ncontract D {\n function testUncheckedOperator() public pure returns (U8) {\n return U8.wrap(250) + U8.wrap(10);\n }\n\n function testUncheckedOperatorInUncheckedBlock() public pure returns (U8) {\n unchecked {\n return U8.wrap(250) + U8.wrap(10);\n }\n }\n}\n// ----\n// testUncheckedOperator() -> 4\n// testUncheckedOperatorInUncheckedBlock() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/optimizer_shift_bytes/shift_bytes.sol b/examples/test/semanticTests/optimizer_shift_bytes/shift_bytes.sol new file mode 100644 index 00000000..6c7eef89 --- /dev/null +++ b/examples/test/semanticTests/optimizer_shift_bytes/shift_bytes.sol @@ -0,0 +1,42 @@ +// This tests the optimizer rule +// byte(A, shl(B, X)) +// -> +// byte(A + B / 8, X) +// given A <= 32 && B % 8 == 0 && B <= 256 +// +// and the respective rule about shr +contract C { + function f(uint a) public returns (uint, uint, uint) { + uint x = a << (256 - 8); + assembly { + x := byte(0, x) + } + uint y = a << 8; + assembly { + y := byte(30, y) + } + uint z = a << 16; + assembly { + z := byte(1, z) + } + return (x, y, z); + } + function g(uint a) public returns (uint, uint, uint) { + uint x = a >> (256 - 16); + assembly { + x := byte(31, x) + } + uint y = a >> 8; + assembly { + y := byte(4, y) + } + uint z = a >> 16; + assembly { + z := byte(7, z) + } + return (x, y, z); + } +} +// ---- +// f(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 0x1f, 0x1f, 3 +// g(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 1, 3, 5 diff --git a/examples/test/semanticTests/optimizer_shift_bytes/shift_bytes_standard_input.json b/examples/test/semanticTests/optimizer_shift_bytes/shift_bytes_standard_input.json new file mode 100644 index 00000000..eeeabea3 --- /dev/null +++ b/examples/test/semanticTests/optimizer_shift_bytes/shift_bytes_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "shift_bytes.sol": { + "content": "// This tests the optimizer rule\n// byte(A, shl(B, X))\n// ->\n// byte(A + B / 8, X)\n// given A <= 32 && B % 8 == 0 && B <= 256\n//\n// and the respective rule about shr\ncontract C {\n function f(uint a) public returns (uint, uint, uint) {\n uint x = a << (256 - 8);\n assembly {\n x := byte(0, x)\n }\n uint y = a << 8;\n assembly {\n y := byte(30, y)\n }\n uint z = a << 16;\n assembly {\n z := byte(1, z)\n }\n return (x, y, z);\n }\n function g(uint a) public returns (uint, uint, uint) {\n uint x = a >> (256 - 16);\n assembly {\n x := byte(31, x)\n }\n uint y = a >> 8;\n assembly {\n y := byte(4, y)\n }\n uint z = a >> 16;\n assembly {\n z := byte(7, z)\n }\n return (x, y, z);\n }\n}\n// ----\n// f(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 0x1f, 0x1f, 3\n// g(uint256): 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f -> 1, 3, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier.sol b/examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier.sol new file mode 100644 index 00000000..c3609591 --- /dev/null +++ b/examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier.sol @@ -0,0 +1,14 @@ +contract C { + modifier tryCircumvent { + if (false) _; // avoid the function, we should still not accept ether + } + function f() tryCircumvent public returns (uint) { + return msgvalue(); + } + function msgvalue() internal returns (uint) { + return msg.value; + } +} +// ---- +// f(), 27 wei -> FAILURE +// balance -> 0 diff --git a/examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier_standard_input.json b/examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier_standard_input.json new file mode 100644 index 00000000..c1228511 --- /dev/null +++ b/examples/test/semanticTests/payable_no_nonpayable_circumvention_by_modifier/no_nonpayable_circumvention_by_modifier_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "no_nonpayable_circumvention_by_modifier.sol": { + "content": "contract C {\n modifier tryCircumvent {\n if (false) _; // avoid the function, we should still not accept ether\n }\n function f() tryCircumvent public returns (uint) {\n return msgvalue();\n }\n function msgvalue() internal returns (uint) {\n return msg.value;\n }\n}\n// ----\n// f(), 27 wei -> FAILURE\n// balance -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive.sol b/examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive.sol new file mode 100644 index 00000000..ce04cd73 --- /dev/null +++ b/examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive.sol @@ -0,0 +1,13 @@ +contract A { + uint public x; + receive () external payable { ++x; } +} +// ---- +// x() -> 0 +// () +// x() -> 1 +// (), 1 wei +// x() -> 2 +// x(), 1 wei -> FAILURE +// (): hex"00" -> FAILURE +// (), 1 ether: hex"00" -> FAILURE diff --git a/examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive_standard_input.json b/examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive_standard_input.json new file mode 100644 index 00000000..dec1ee0c --- /dev/null +++ b/examples/test/semanticTests/receive_empty_calldata_calls_receive/empty_calldata_calls_receive_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "empty_calldata_calls_receive.sol": { + "content": "contract A {\n uint public x;\n receive () external payable { ++x; }\n}\n// ----\n// x() -> 0\n// ()\n// x() -> 1\n// (), 1 wei\n// x() -> 2\n// x(), 1 wei -> FAILURE\n// (): hex\"00\" -> FAILURE\n// (), 1 ether: hex\"00\" -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/receive_ether_and_data/ether_and_data.sol b/examples/test/semanticTests/receive_ether_and_data/ether_and_data.sol new file mode 100644 index 00000000..4c48df8d --- /dev/null +++ b/examples/test/semanticTests/receive_ether_and_data/ether_and_data.sol @@ -0,0 +1,6 @@ +contract C { + receive () payable external { } +} +// ---- +// (), 1 ether +// (), 1 ether: 1 -> FAILURE diff --git a/examples/test/semanticTests/receive_ether_and_data/ether_and_data_standard_input.json b/examples/test/semanticTests/receive_ether_and_data/ether_and_data_standard_input.json new file mode 100644 index 00000000..de745f79 --- /dev/null +++ b/examples/test/semanticTests/receive_ether_and_data/ether_and_data_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "empty_calldata_calls_receive.sol": { + "content": "contract A {\n uint public x;\n receive () external payable { ++x; }\n}\n// ----\n// x() -> 0\n// ()\n// x() -> 1\n// (), 1 wei\n// x() -> 2\n// x(), 1 wei -> FAILURE\n// (): hex\"00\" -> FAILURE\n// (), 1 ether: hex\"00\" -> FAILURE\n" + }, + "inherited.sol": { + "content": "contract A {\n uint data;\n receive() external payable { ++data; }\n function getData() public returns (uint r) { return data; }\n}\ncontract B is A {}\n// ----\n// getData() -> 0\n// () ->\n// getData() -> 1\n// (), 1 ether ->\n// getData() -> 2\n" + }, + "ether_and_data.sol": { + "content": "contract C {\n receive () payable external { }\n}\n// ----\n// (), 1 ether\n// (), 1 ether: 1 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/receive_inherited/inherited.sol b/examples/test/semanticTests/receive_inherited/inherited.sol new file mode 100644 index 00000000..36273068 --- /dev/null +++ b/examples/test/semanticTests/receive_inherited/inherited.sol @@ -0,0 +1,12 @@ +contract A { + uint data; + receive() external payable { ++data; } + function getData() public returns (uint r) { return data; } +} +contract B is A {} +// ---- +// getData() -> 0 +// () -> +// getData() -> 1 +// (), 1 ether -> +// getData() -> 2 diff --git a/examples/test/semanticTests/receive_inherited/inherited_standard_input.json b/examples/test/semanticTests/receive_inherited/inherited_standard_input.json new file mode 100644 index 00000000..3268deaa --- /dev/null +++ b/examples/test/semanticTests/receive_inherited/inherited_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "empty_calldata_calls_receive.sol": { + "content": "contract A {\n uint public x;\n receive () external payable { ++x; }\n}\n// ----\n// x() -> 0\n// ()\n// x() -> 1\n// (), 1 wei\n// x() -> 2\n// x(), 1 wei -> FAILURE\n// (): hex\"00\" -> FAILURE\n// (), 1 ether: hex\"00\" -> FAILURE\n" + }, + "inherited.sol": { + "content": "contract A {\n uint data;\n receive() external payable { ++data; }\n function getData() public returns (uint r) { return data; }\n}\ncontract B is A {}\n// ----\n// getData() -> 0\n// () ->\n// getData() -> 1\n// (), 1 ether ->\n// getData() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_array_slices/array_slices.sol b/examples/test/semanticTests/revertStrings_array_slices/array_slices.sol new file mode 100644 index 00000000..dec3e916 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_array_slices/array_slices.sol @@ -0,0 +1,11 @@ +contract C { + function f(uint256 start, uint256 end, uint256[] calldata arr) external pure { + arr[start:end]; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex"08c379a0", 0x20, 22, "Slice starts after end" +// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex"08c379a0", 0x20, 28, "Slice is greater than length" diff --git a/examples/test/semanticTests/revertStrings_array_slices/array_slices_standard_input.json b/examples/test/semanticTests/revertStrings_array_slices/array_slices_standard_input.json new file mode 100644 index 00000000..5aa1b48c --- /dev/null +++ b/examples/test/semanticTests/revertStrings_array_slices/array_slices_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_bubble/bubble.sol b/examples/test/semanticTests/revertStrings_bubble/bubble.sol new file mode 100644 index 00000000..5e9a0730 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_bubble/bubble.sol @@ -0,0 +1,15 @@ +contract A { + function g() public { revert("fail"); } +} + +contract C { + A a = new A(); + function f() public { + a.g(); + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f() -> FAILURE, hex"08c379a0", 0x20, 4, "fail" diff --git a/examples/test/semanticTests/revertStrings_bubble/bubble_standard_input.json b/examples/test/semanticTests/revertStrings_bubble/bubble_standard_input.json new file mode 100644 index 00000000..c3e2f740 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_bubble/bubble_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol new file mode 100644 index 00000000..355c4722 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; +contract C { + function f(uint256[][] calldata a) external returns (uint) { + return 42; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256[][]): 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI decoding: invalid calldata a", "rray stride" diff --git a/examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json new file mode 100644 index 00000000..b34564b3 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_invalid/calldata_array_dynamic_invalid_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol new file mode 100644 index 00000000..7c5ba33b --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode.sol @@ -0,0 +1,12 @@ +pragma abicoder v2; +contract C { + function f(uint256[][2][] calldata x) external returns (uint256) { + x[0]; + return 23; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex"08c379a0", 0x20, 28, "Invalid calldata tail offset" diff --git a/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json new file mode 100644 index 00000000..b82c4f23 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_decode/calldata_array_dynamic_static_short_decode_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol new file mode 100644 index 00000000..77341fa2 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode.sol @@ -0,0 +1,14 @@ +pragma abicoder v2; +contract C { + function f(uint256[][2][] calldata x) external returns (uint256) { + return 42; + } + function g(uint256[][2][] calldata x) external returns (uint256) { + return this.f(x); + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex"08c379a0", 0x20, 30, "Invalid calldata access offset" diff --git a/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json new file mode 100644 index 00000000..cb9415d9 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_dynamic_static_short_reencode/calldata_array_dynamic_static_short_reencode_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + }, + "calldata_tail_short.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n" + }, + "function_entry_checks_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Calldata too short\"\n" + }, + "short_input_array.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint[] memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 30, \"Invalid calldata access offset\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length.sol b/examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length.sol new file mode 100644 index 00000000..4af015f3 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; +contract C { + function f(uint256[][] calldata x) external returns (uint256) { + return x[0].length; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 28, "Invalid calldata tail length" diff --git a/examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length_standard_input.json new file mode 100644 index 00000000..e7174567 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_array_invalid_length/calldata_array_invalid_length_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large.sol b/examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large.sol new file mode 100644 index 00000000..34a6f0a0 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; +contract C { + function f(uint a, uint[] calldata b, uint c) external pure returns (uint) { + return 7; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI decoding: invalid calldata a", "rray length" diff --git a/examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json new file mode 100644 index 00000000..a4104738 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_arrays_too_large/calldata_arrays_too_large_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short.sol b/examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short.sol new file mode 100644 index 00000000..c0c1e3f4 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short.sol @@ -0,0 +1,9 @@ +pragma abicoder v2; +contract C { + function f(uint256[][] calldata x) external { x[0]; } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex"08c379a0", 0x20, 23, "Calldata tail too short" diff --git a/examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short_standard_input.json new file mode 100644 index 00000000..50b7d57d --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_tail_short/calldata_tail_short_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + }, + "calldata_tail_short.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1.sol b/examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1.sol new file mode 100644 index 00000000..4677d350 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1.sol @@ -0,0 +1,13 @@ +pragma abicoder v1; +contract C { + function d(bytes memory _data) public pure returns (uint8) { + return abi.decode(_data, (uint8)); + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 18, "Calldata too short" diff --git a/examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1_standard_input.json b/examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1_standard_input.json new file mode 100644 index 00000000..0f664e35 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_calldata_too_short_v1/calldata_too_short_v1_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code.sol b/examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code.sol new file mode 100644 index 00000000..110b1e50 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code.sol @@ -0,0 +1,12 @@ +contract C { + function f() external {} + function g() external { + C c = C(address(0x0000000000000000000000000000000000000000000000000000000000000000)); + c.f(); + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// g() -> FAILURE, hex"08c379a0", 0x20, 37, "Target contract does not contain", " code" diff --git a/examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code_standard_input.json b/examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code_standard_input.json new file mode 100644 index 00000000..4e5f8138 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_called_contract_has_code/called_contract_has_code_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + }, + "calldata_tail_short.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n" + }, + "function_entry_checks_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Calldata too short\"\n" + }, + "short_input_array.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint[] memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 30, \"Invalid calldata access offset\"\n" + }, + "called_contract_has_code.sol": { + "content": "contract C {\n\tfunction f() external {}\n\tfunction g() external {\n\t\tC c = C(address(0x0000000000000000000000000000000000000000000000000000000000000000));\n\t\tc.f();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// g() -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_empty_v1/empty_v1.sol b/examples/test/semanticTests/revertStrings_empty_v1/empty_v1.sol new file mode 100644 index 00000000..b9658c79 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_empty_v1/empty_v1.sol @@ -0,0 +1,18 @@ +pragma abicoder v1; +contract C { + function f() public { + revert(""); + } + function g(string calldata msg) public { + revert(msg); + } +} +// ==== +// ABIEncoderV1Only: true +// EVMVersion: >=byzantium +// revertStrings: debug +// compileViaYul: false +// ---- +// f() -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0 diff --git a/examples/test/semanticTests/revertStrings_empty_v1/empty_v1_standard_input.json b/examples/test/semanticTests/revertStrings_empty_v1/empty_v1_standard_input.json new file mode 100644 index 00000000..72c9eb32 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_empty_v1/empty_v1_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_empty_v2/empty_v2.sol b/examples/test/semanticTests/revertStrings_empty_v2/empty_v2.sol new file mode 100644 index 00000000..24a68490 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_empty_v2/empty_v2.sol @@ -0,0 +1,17 @@ +pragma abicoder v2; +contract C { + function f() public { + revert(""); + } + function g(string calldata msg) public { + revert(msg); + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f() -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0, "" -> FAILURE, hex"08c379a0", 0x20, 0 +// g(string): 0x20, 0 -> FAILURE, hex"08c379a0", 0x20, 0 diff --git a/examples/test/semanticTests/revertStrings_empty_v2/empty_v2_standard_input.json b/examples/test/semanticTests/revertStrings_empty_v2/empty_v2_standard_input.json new file mode 100644 index 00000000..c3a73922 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_empty_v2/empty_v2_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_enum_v1/enum_v1.sol b/examples/test/semanticTests/revertStrings_enum_v1/enum_v1.sol new file mode 100644 index 00000000..305e43a5 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_enum_v1/enum_v1.sol @@ -0,0 +1,14 @@ +pragma abicoder v1; +contract C { + enum E {X, Y} + function f(E[] calldata arr) external { + arr[1]; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex"08c379a0", 0x20, 17, "Enum out of range" diff --git a/examples/test/semanticTests/revertStrings_enum_v1/enum_v1_standard_input.json b/examples/test/semanticTests/revertStrings_enum_v1/enum_v1_standard_input.json new file mode 100644 index 00000000..257cfdac --- /dev/null +++ b/examples/test/semanticTests/revertStrings_enum_v1/enum_v1_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_enum_v2/enum_v2.sol b/examples/test/semanticTests/revertStrings_enum_v2/enum_v2.sol new file mode 100644 index 00000000..e2f77e55 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_enum_v2/enum_v2.sol @@ -0,0 +1,12 @@ +pragma abicoder v2; +contract C { + enum E {X, Y} + function f(E[] calldata arr) external { + arr[1]; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE diff --git a/examples/test/semanticTests/revertStrings_enum_v2/enum_v2_standard_input.json b/examples/test/semanticTests/revertStrings_enum_v2/enum_v2_standard_input.json new file mode 100644 index 00000000..c471a7c3 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_enum_v2/enum_v2_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function.sol b/examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function.sol new file mode 100644 index 00000000..ffaea687 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function.sol @@ -0,0 +1,9 @@ +contract C { + function f() public {} +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(), 1 ether -> FAILURE, hex"08c379a0", 0x20, 34, "Ether sent to non-payable functi", "on" +// () -> FAILURE, hex"08c379a0", 0x20, 53, "Contract does not have fallback ", "nor receive functions" diff --git a/examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function_standard_input.json b/examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function_standard_input.json new file mode 100644 index 00000000..32055593 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_ether_non_payable_function/ether_non_payable_function_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1.sol b/examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1.sol new file mode 100644 index 00000000..13c3d854 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1.sol @@ -0,0 +1,11 @@ +pragma abicoder v1; +contract C { + function t(uint) public pure {} +} +// ==== +// EVMVersion: >=byzantium +// ABIEncoderV1Only: true +// revertStrings: debug +// compileViaYul: false +// ---- +// t(uint256) -> FAILURE, hex"08c379a0", 0x20, 0x12, "Calldata too short" diff --git a/examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1_standard_input.json b/examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1_standard_input.json new file mode 100644 index 00000000..7515b231 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_function_entry_checks_v1/function_entry_checks_v1_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + }, + "calldata_tail_short.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n" + }, + "function_entry_checks_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Calldata too short\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2.sol b/examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2.sol new file mode 100644 index 00000000..3412f58c --- /dev/null +++ b/examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2.sol @@ -0,0 +1,9 @@ +pragma abicoder v2; +contract C { + function t(uint) public pure {} +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// t(uint256) -> FAILURE, hex"08c379a0", 0x20, 34, "ABI decoding: tuple data too sho", "rt" diff --git a/examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2_standard_input.json b/examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2_standard_input.json new file mode 100644 index 00000000..b2e95b16 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_function_entry_checks_v2/function_entry_checks_v2_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + }, + "calldata_tail_short.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n" + }, + "function_entry_checks_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Calldata too short\"\n" + }, + "short_input_array.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint[] memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "calldata_array_dynamic_static_short_reencode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n return 42;\n }\n function g(uint256[][2][] calldata x) external returns (uint256) {\n return this.f(x);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// g(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 30, \"Invalid calldata access offset\"\n" + }, + "called_contract_has_code.sol": { + "content": "contract C {\n\tfunction f() external {}\n\tfunction g() external {\n\t\tC c = C(address(0x0000000000000000000000000000000000000000000000000000000000000000));\n\t\tc.f();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// g() -> FAILURE, hex\"08c379a0\", 0x20, 37, \"Target contract does not contain\", \" code\"\n" + }, + "function_entry_checks_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 34, \"ABI decoding: tuple data too sho\", \"rt\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1.sol b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1.sol new file mode 100644 index 00000000..41cd0f4d --- /dev/null +++ b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1.sol @@ -0,0 +1,15 @@ +pragma abicoder v1; +contract C { + function d(bytes memory _data) public pure returns (uint8) { + return abi.decode(_data, (uint8)); + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0 +// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI calldata decoding: invalid h", "ead pointer" +// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI calldata decoding: invalid d", "ata pointer" diff --git a/examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1_standard_input.json b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1_standard_input.json new file mode 100644 index 00000000..cff37527 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_calldata_v1/invalid_abi_decoding_calldata_v1_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1.sol b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1.sol new file mode 100644 index 00000000..af9d822d --- /dev/null +++ b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1.sol @@ -0,0 +1,22 @@ +pragma abicoder v1; +contract C { + function dyn(uint ptr, uint start, uint x) public returns (bytes memory a) { + assembly { + mstore(0, start) + mstore(start, add(start, 1)) + return(ptr, x) + } + } + function f(uint ptr, uint start, uint x) public returns (bool) { + this.dyn(ptr, start, x); + return true; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex"08c379a0", 0x20, 39, "ABI memory decoding: invalid dat", "a start" +// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex"08c379a0", 0x20, 40, "ABI memory decoding: invalid dat", "a length" diff --git a/examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1_standard_input.json b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1_standard_input.json new file mode 100644 index 00000000..ce6a1ac1 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_invalid_abi_decoding_memory_v1/invalid_abi_decoding_memory_v1_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call.sol b/examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call.sol new file mode 100644 index 00000000..1a079a04 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call.sol @@ -0,0 +1,16 @@ +library L { + function g() external {} +} +contract C { + function f() public returns (bytes memory) { + (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature("g()")); + assert(!success); + return result; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// library: L +// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0 diff --git a/examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call_standard_input.json b/examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call_standard_input.json new file mode 100644 index 00000000..c77273dc --- /dev/null +++ b/examples/test/semanticTests/revertStrings_library_non_view_call/library_non_view_call_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_short_input_array/short_input_array.sol b/examples/test/semanticTests/revertStrings_short_input_array/short_input_array.sol new file mode 100644 index 00000000..4a96accf --- /dev/null +++ b/examples/test/semanticTests/revertStrings_short_input_array/short_input_array.sol @@ -0,0 +1,9 @@ +pragma abicoder v2; +contract C { + function f(uint[] memory a) public pure returns (uint) { return 7; } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// f(uint256[]): 0x20, 1 -> FAILURE, hex"08c379a0", 0x20, 43, "ABI decoding: invalid calldata a", "rray stride" diff --git a/examples/test/semanticTests/revertStrings_short_input_array/short_input_array_standard_input.json b/examples/test/semanticTests/revertStrings_short_input_array/short_input_array_standard_input.json new file mode 100644 index 00000000..0676be52 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_short_input_array/short_input_array_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + }, + "bubble.sol": { + "content": "contract A {\n\tfunction g() public { revert(\"fail\"); }\n}\n\ncontract C {\n\tA a = new A();\n\tfunction f() public {\n\t\ta.g();\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 4, \"fail\"\n" + }, + "calldata_array_dynamic_static_short_decode.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][2][] calldata x) external returns (uint256) {\n x[0];\n return 23;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][2][]): 0x20, 0x01, 0x20, 0x00 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail offset\"\n" + }, + "library_non_view_call.sol": { + "content": "library L {\n function g() external {}\n}\ncontract C {\n function f() public returns (bytes memory) {\n (bool success, bytes memory result) = address(L).call(abi.encodeWithSignature(\"g()\"));\n\t\tassert(!success);\n\t\treturn result;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// library: L\n// f() -> 32, 132, 3963877391197344453575983046348115674221700746820753546331534351508065746944, 862718293348820473429344482784628181556388621521298319395315527974912, 1518017211910606845658622928256476421055725129218887721595913401102969, 14649601406562900601407788686537400806574002225747213573947654179243427889152, 0\n" + }, + "invalid_abi_decoding_calldata_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> 0\n// d(bytes): 0x100, 0x20, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid h\", \"ead pointer\"\n// d(bytes): 0x20, 0x100, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI calldata decoding: invalid d\", \"ata pointer\"\n" + }, + "invalid_abi_decoding_memory_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction dyn(uint ptr, uint start, uint x) public returns (bytes memory a) {\n\t\tassembly {\n\t\t\tmstore(0, start)\n\t\t\tmstore(start, add(start, 1))\n\t\t\treturn(ptr, x)\n\t\t}\n\t}\n\tfunction f(uint ptr, uint start, uint x) public returns (bool) {\n\t\tthis.dyn(ptr, start, x);\n\t\treturn true;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint256,uint256,uint256): 0, 0x200, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI memory decoding: invalid dat\", \"a start\"\n// f(uint256,uint256,uint256): 0, 0x20, 0x60 -> FAILURE, hex\"08c379a0\", 0x20, 40, \"ABI memory decoding: invalid dat\", \"a length\"\n" + }, + "calldata_arrays_too_large.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint a, uint[] calldata b, uint c) external pure returns (uint) {\n\t\treturn 7;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256[],uint256): 6, 0x60, 9, 0x1000000000000000000000000000000000000000000000000000000000000002, 1, 2 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray length\"\n" + }, + "calldata_array_invalid_length.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata x) external returns (uint256) {\n\t\treturn x[0].length;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 0x0100000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Invalid calldata tail length\"\n" + }, + "array_slices.sol": { + "content": "contract C {\n\tfunction f(uint256 start, uint256 end, uint256[] calldata arr) external pure {\n\t\tarr[start:end];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256,uint256,uint256[]): 2, 1, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 22, \"Slice starts after end\"\n// f(uint256,uint256,uint256[]): 1, 5, 0x80, 3, 1, 2, 3 -> FAILURE, hex\"08c379a0\", 0x20, 28, \"Slice is greater than length\"\n" + }, + "calldata_tail_short.sol": { + "content": "pragma abicoder v2;\ncontract C {\n function f(uint256[][] calldata x) external { x[0]; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1, 0x20, 2, 0x42 -> FAILURE, hex\"08c379a0\", 0x20, 23, \"Calldata tail too short\"\n" + }, + "function_entry_checks_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n function t(uint) public pure {}\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// t(uint256) -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Calldata too short\"\n" + }, + "short_input_array.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint[] memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes.sol b/examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes.sol new file mode 100644 index 00000000..2f275b86 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes.sol @@ -0,0 +1,9 @@ +pragma abicoder v2; +contract C { + function e(bytes memory a) public pure returns (uint) { return 7; } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// e(bytes): 0x20, 7 -> FAILURE, hex"08c379a0", 0x20, 39, "ABI decoding: invalid byte array", " length" diff --git a/examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes_standard_input.json b/examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes_standard_input.json new file mode 100644 index 00000000..ad7e325e --- /dev/null +++ b/examples/test/semanticTests/revertStrings_short_input_bytes/short_input_bytes_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_transfer/transfer.sol b/examples/test/semanticTests/revertStrings_transfer/transfer.sol new file mode 100644 index 00000000..ef2e7285 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_transfer/transfer.sol @@ -0,0 +1,27 @@ +contract A { + receive() external payable { + revert("no_receive"); + } +} + +contract C { + A a = new A(); + receive() external payable {} + function f() public { + payable(a).transfer(1 wei); + } + function h() public { + payable(a).transfer(100 ether); + } + function g() public view returns (uint) { + return payable(this).balance; + } +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// (), 10 wei -> +// g() -> 10 +// f() -> FAILURE, hex"08c379a0", 0x20, 10, "no_receive" +// h() -> FAILURE diff --git a/examples/test/semanticTests/revertStrings_transfer/transfer_standard_input.json b/examples/test/semanticTests/revertStrings_transfer/transfer_standard_input.json new file mode 100644 index 00000000..eb8a0785 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_transfer/transfer_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + }, + "enum_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE, hex\"08c379a0\", 0x20, 17, \"Enum out of range\"\n" + }, + "empty_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "ether_non_payable_function.sol": { + "content": "contract C {\n\tfunction f() public {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(), 1 ether -> FAILURE, hex\"08c379a0\", 0x20, 34, \"Ether sent to non-payable functi\", \"on\"\n// () -> FAILURE, hex\"08c379a0\", 0x20, 53, \"Contract does not have fallback \", \"nor receive functions\"\n" + }, + "enum_v2.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tenum E {X, Y}\n\tfunction f(E[] calldata arr) external {\n\t\tarr[1];\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint8[]): 0x20, 2, 3, 3 -> FAILURE\n" + }, + "calldata_array_dynamic_invalid.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction f(uint256[][] calldata a) external returns (uint) {\n\t\treturn 42;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// f(uint256[][]): 0x20, 1 -> FAILURE, hex\"08c379a0\", 0x20, 43, \"ABI decoding: invalid calldata a\", \"rray stride\"\n" + }, + "transfer.sol": { + "content": "contract A {\n\treceive() external payable {\n\t\trevert(\"no_receive\");\n\t}\n}\n\ncontract C {\n\tA a = new A();\n\treceive() external payable {}\n\tfunction f() public {\n\t\tpayable(a).transfer(1 wei);\n\t}\n\tfunction h() public {\n\t\tpayable(a).transfer(100 ether);\n\t}\n\tfunction g() public view returns (uint) {\n\t\treturn payable(this).balance;\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (), 10 wei ->\n// g() -> 10\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 10, \"no_receive\"\n// h() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback.sol b/examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback.sol new file mode 100644 index 00000000..62b24588 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback.sol @@ -0,0 +1,8 @@ +contract A { + receive () external payable {} +} +// ==== +// EVMVersion: >=byzantium +// revertStrings: debug +// ---- +// (): hex"00" -> FAILURE, hex"08c379a0", 0x20, 41, "Unknown signature and no fallbac", "k defined" diff --git a/examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback_standard_input.json b/examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback_standard_input.json new file mode 100644 index 00000000..fc384817 --- /dev/null +++ b/examples/test/semanticTests/revertStrings_unknown_sig_no_fallback/unknown_sig_no_fallback_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "short_input_bytes.sol": { + "content": "pragma abicoder v2;\ncontract C {\n\tfunction e(bytes memory a) public pure returns (uint) { return 7; }\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// e(bytes): 0x20, 7 -> FAILURE, hex\"08c379a0\", 0x20, 39, \"ABI decoding: invalid byte array\", \" length\"\n" + }, + "calldata_too_short_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction d(bytes memory _data) public pure returns (uint8) {\n\t\treturn abi.decode(_data, (uint8));\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// d(bytes): 0x20, 0x01, 0x0000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"08c379a0\", 0x20, 18, \"Calldata too short\"\n" + }, + "empty_v1.sol": { + "content": "pragma abicoder v1;\ncontract C {\n\tfunction f() public {\n\t\trevert(\"\");\n\t}\n\tfunction g(string calldata msg) public {\n\t\trevert(msg);\n\t}\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// compileViaYul: false\n// ----\n// f() -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0, \"\" -> FAILURE, hex\"08c379a0\", 0x20, 0\n// g(string): 0x20, 0 -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "unknown_sig_no_fallback.sol": { + "content": "contract A {\n\treceive () external payable {}\n}\n// ====\n// EVMVersion: >=byzantium\n// revertStrings: debug\n// ----\n// (): hex\"00\" -> FAILURE, hex\"08c379a0\", 0x20, 41, \"Unknown signature and no fallbac\", \"k defined\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_assert_require/assert_require.sol b/examples/test/semanticTests/reverts_assert_require/assert_require.sol new file mode 100644 index 00000000..bc4db360 --- /dev/null +++ b/examples/test/semanticTests/reverts_assert_require/assert_require.sol @@ -0,0 +1,21 @@ +contract C { + function f() public { + assert(false); + } + + function g(bool val) public returns (bool) { + assert(val == true); + return true; + } + + function h(bool val) public returns (bool) { + require(val); + return true; + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x01 +// g(bool): false -> FAILURE, hex"4e487b71", 0x01 +// g(bool): true -> true +// h(bool): false -> FAILURE +// h(bool): true -> true diff --git a/examples/test/semanticTests/reverts_assert_require/assert_require_standard_input.json b/examples/test/semanticTests/reverts_assert_require/assert_require_standard_input.json new file mode 100644 index 00000000..428384dc --- /dev/null +++ b/examples/test/semanticTests/reverts_assert_require/assert_require_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + }, + "revert_return_area.sol": { + "content": "contract C {\n fallback() external {\n revert(\"abc\");\n }\n\n function f() public returns (uint s, uint r) {\n address x = address(this);\n assembly {\n mstore(0, 7)\n s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n r := mload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n" + }, + "invalid_instruction.sol": { + "content": "contract C {\n function f() public {\n assembly {\n invalid()\n }\n }\n}\n// ----\n// f() -> FAILURE\n" + }, + "invalid_enum_as_external_arg.sol": { + "content": "contract C {\n enum X {A, B}\n\n function tested(X x) public returns (uint256) {\n return 1;\n }\n\n function test() public returns (uint256) {\n X garbled;\n\n assembly {\n garbled := 5\n }\n\n return this.tested(garbled);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x21 # should throw #\n" + }, + "invalid_enum_as_external_ret.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_return() public returns (X) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled;\n }\n\n function test_inline_assignment() public returns (X _ret) {\n assembly {\n _ret := 5\n }\n }\n\n function test_assignment() public returns (X _ret) {\n X tmp;\n assembly {\n tmp := 5\n }\n _ret = tmp;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_return() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_inline_assignment() -> FAILURE, hex\"4e487b71\", 33\n// test_assignment() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assert_require.sol": { + "content": "contract C {\n function f() public {\n assert(false);\n }\n\n function g(bool val) public returns (bool) {\n assert(val == true);\n return true;\n }\n\n function h(bool val) public returns (bool) {\n require(val);\n return true;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x01\n// g(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// g(bool): true -> true\n// h(bool): false -> FAILURE\n// h(bool): true -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_error_struct/error_struct.sol b/examples/test/semanticTests/reverts_error_struct/error_struct.sol new file mode 100644 index 00000000..d6171a41 --- /dev/null +++ b/examples/test/semanticTests/reverts_error_struct/error_struct.sol @@ -0,0 +1,15 @@ +struct error { uint error; } +contract C { + error test(); + error _struct; + function f() public { + revert test(); + } + function g(uint x) public returns (uint) { + _struct.error = x; + return _struct.error; + } +} +// ---- +// f() -> FAILURE, hex"f8a8fd6d" +// g(uint256): 7 -> 7 diff --git a/examples/test/semanticTests/reverts_error_struct/error_struct_standard_input.json b/examples/test/semanticTests/reverts_error_struct/error_struct_standard_input.json new file mode 100644 index 00000000..1fa2ec69 --- /dev/null +++ b/examples/test/semanticTests/reverts_error_struct/error_struct_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg.sol b/examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg.sol new file mode 100644 index 00000000..28c4e01f --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg.sol @@ -0,0 +1,21 @@ +contract C { + enum X {A, B} + + function tested(X x) public returns (uint256) { + return 1; + } + + function test() public returns (uint256) { + X garbled; + + assembly { + garbled := 5 + } + + return this.tested(garbled); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// test() -> FAILURE, hex"4e487b71", 0x21 # should throw # diff --git a/examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg_standard_input.json b/examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg_standard_input.json new file mode 100644 index 00000000..70fdf743 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_as_external_arg/invalid_enum_as_external_arg_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + }, + "revert_return_area.sol": { + "content": "contract C {\n fallback() external {\n revert(\"abc\");\n }\n\n function f() public returns (uint s, uint r) {\n address x = address(this);\n assembly {\n mstore(0, 7)\n s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n r := mload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n" + }, + "invalid_instruction.sol": { + "content": "contract C {\n function f() public {\n assembly {\n invalid()\n }\n }\n}\n// ----\n// f() -> FAILURE\n" + }, + "invalid_enum_as_external_arg.sol": { + "content": "contract C {\n enum X {A, B}\n\n function tested(X x) public returns (uint256) {\n return 1;\n }\n\n function test() public returns (uint256) {\n X garbled;\n\n assembly {\n garbled := 5\n }\n\n return this.tested(garbled);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x21 # should throw #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret.sol b/examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret.sol new file mode 100644 index 00000000..7416d295 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret.sol @@ -0,0 +1,31 @@ +contract C { + enum X {A, B} + + function test_return() public returns (X) { + X garbled; + assembly { + garbled := 5 + } + return garbled; + } + + function test_inline_assignment() public returns (X _ret) { + assembly { + _ret := 5 + } + } + + function test_assignment() public returns (X _ret) { + X tmp; + assembly { + tmp := 5 + } + _ret = tmp; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// test_return() -> FAILURE, hex"4e487b71", 33 # both should throw # +// test_inline_assignment() -> FAILURE, hex"4e487b71", 33 +// test_assignment() -> FAILURE, hex"4e487b71", 33 diff --git a/examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret_standard_input.json b/examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret_standard_input.json new file mode 100644 index 00000000..ecc866c6 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_as_external_ret/invalid_enum_as_external_ret_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + }, + "revert_return_area.sol": { + "content": "contract C {\n fallback() external {\n revert(\"abc\");\n }\n\n function f() public returns (uint s, uint r) {\n address x = address(this);\n assembly {\n mstore(0, 7)\n s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n r := mload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n" + }, + "invalid_instruction.sol": { + "content": "contract C {\n function f() public {\n assembly {\n invalid()\n }\n }\n}\n// ----\n// f() -> FAILURE\n" + }, + "invalid_enum_as_external_arg.sol": { + "content": "contract C {\n enum X {A, B}\n\n function tested(X x) public returns (uint256) {\n return 1;\n }\n\n function test() public returns (uint256) {\n X garbled;\n\n assembly {\n garbled := 5\n }\n\n return this.tested(garbled);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x21 # should throw #\n" + }, + "invalid_enum_as_external_ret.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_return() public returns (X) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled;\n }\n\n function test_inline_assignment() public returns (X _ret) {\n assembly {\n _ret := 5\n }\n }\n\n function test_assignment() public returns (X _ret) {\n X tmp;\n assembly {\n tmp := 5\n }\n _ret = tmp;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_return() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_inline_assignment() -> FAILURE, hex\"4e487b71\", 33\n// test_assignment() -> FAILURE, hex\"4e487b71\", 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared.sol b/examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared.sol new file mode 100644 index 00000000..527a4320 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared.sol @@ -0,0 +1,30 @@ +contract C { + enum X {A, B} + + function test_eq() public returns (bool) { + X garbled; + assembly { + garbled := 5 + } + return garbled == garbled; + } + + function test_eq_ok() public returns (bool) { + X garbled = X.A; + return garbled == garbled; + } + + function test_neq() public returns (bool) { + X garbled; + assembly { + garbled := 5 + } + return garbled != garbled; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// test_eq_ok() -> 1 +// test_eq() -> FAILURE, hex"4e487b71", 33 # both should throw # +// test_neq() -> FAILURE, hex"4e487b71", 33 diff --git a/examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared_standard_input.json b/examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared_standard_input.json new file mode 100644 index 00000000..ede23123 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_compared/invalid_enum_compared_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored.sol b/examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored.sol new file mode 100644 index 00000000..8049a977 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored.sol @@ -0,0 +1,24 @@ +contract C { + enum X {A, B} + X public x; + + function test_store() public returns (uint256) { + X garbled = X.A; + assembly { + garbled := 5 + } + x = garbled; + return 1; + } + + function test_store_ok() public returns (uint256) { + x = X.A; + return 1; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// test_store_ok() -> 1 +// x() -> 0 +// test_store() -> FAILURE, hex"4e487b71", 33 # should throw # diff --git a/examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored_standard_input.json b/examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored_standard_input.json new file mode 100644 index 00000000..d45e0b38 --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_enum_stored/invalid_enum_stored_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction.sol b/examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction.sol new file mode 100644 index 00000000..69d9a0cd --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction.sol @@ -0,0 +1,9 @@ +contract C { + function f() public { + assembly { + invalid() + } + } +} +// ---- +// f() -> FAILURE diff --git a/examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction_standard_input.json b/examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction_standard_input.json new file mode 100644 index 00000000..31955bfd --- /dev/null +++ b/examples/test/semanticTests/reverts_invalid_instruction/invalid_instruction_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + }, + "revert_return_area.sol": { + "content": "contract C {\n fallback() external {\n revert(\"abc\");\n }\n\n function f() public returns (uint s, uint r) {\n address x = address(this);\n assembly {\n mstore(0, 7)\n s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n r := mload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n" + }, + "invalid_instruction.sol": { + "content": "contract C {\n function f() public {\n assembly {\n invalid()\n }\n }\n}\n// ----\n// f() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_revert/revert.sol b/examples/test/semanticTests/reverts_revert/revert.sol new file mode 100644 index 00000000..2d733b4e --- /dev/null +++ b/examples/test/semanticTests/reverts_revert/revert.sol @@ -0,0 +1,20 @@ +contract C { + uint256 public a = 42; + + function f() public { + a = 1; + revert(); + } + + function g() public { + a = 1; + assembly { + revert(0, 0) + } + } +} +// ---- +// f() -> FAILURE +// a() -> 42 +// g() -> FAILURE +// a() -> 42 diff --git a/examples/test/semanticTests/reverts_revert/revert_standard_input.json b/examples/test/semanticTests/reverts_revert/revert_standard_input.json new file mode 100644 index 00000000..388ebffd --- /dev/null +++ b/examples/test/semanticTests/reverts_revert/revert_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_revert_return_area/revert_return_area.sol b/examples/test/semanticTests/reverts_revert_return_area/revert_return_area.sol new file mode 100644 index 00000000..8ab4ca22 --- /dev/null +++ b/examples/test/semanticTests/reverts_revert_return_area/revert_return_area.sol @@ -0,0 +1,18 @@ +contract C { + fallback() external { + revert("abc"); + } + + function f() public returns (uint s, uint r) { + address x = address(this); + assembly { + mstore(0, 7) + s := call(sub(0, 1), x, 0, 0, 0, 0, 32) + r := mload(0) + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/reverts_revert_return_area/revert_return_area_standard_input.json b/examples/test/semanticTests/reverts_revert_return_area/revert_return_area_standard_input.json new file mode 100644 index 00000000..e7feaf83 --- /dev/null +++ b/examples/test/semanticTests/reverts_revert_return_area/revert_return_area_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + }, + "revert_return_area.sol": { + "content": "contract C {\n fallback() external {\n revert(\"abc\");\n }\n\n function f() public returns (uint s, uint r) {\n address x = address(this);\n assembly {\n mstore(0, 7)\n s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n r := mload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/reverts_simple_throw/simple_throw.sol b/examples/test/semanticTests/reverts_simple_throw/simple_throw.sol new file mode 100644 index 00000000..1c1bfee0 --- /dev/null +++ b/examples/test/semanticTests/reverts_simple_throw/simple_throw.sol @@ -0,0 +1,10 @@ +contract Test { + function f(uint256 x) public returns (uint256) { + if (x > 10) return x + 10; + else revert(); + return 2; + } +} +// ---- +// f(uint256): 11 -> 21 +// f(uint256): 1 -> FAILURE diff --git a/examples/test/semanticTests/reverts_simple_throw/simple_throw_standard_input.json b/examples/test/semanticTests/reverts_simple_throw/simple_throw_standard_input.json new file mode 100644 index 00000000..27d09e1c --- /dev/null +++ b/examples/test/semanticTests/reverts_simple_throw/simple_throw_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "invalid_enum_stored.sol": { + "content": "contract C {\n enum X {A, B}\n X public x;\n\n function test_store() public returns (uint256) {\n X garbled = X.A;\n assembly {\n garbled := 5\n }\n x = garbled;\n return 1;\n }\n\n function test_store_ok() public returns (uint256) {\n x = X.A;\n return 1;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_store_ok() -> 1\n// x() -> 0\n// test_store() -> FAILURE, hex\"4e487b71\", 33 # should throw #\n" + }, + "error_struct.sol": { + "content": "struct error { uint error; }\ncontract C {\n\terror test();\n\terror _struct;\n\tfunction f() public {\n\t\trevert test();\n\t}\n\tfunction g(uint x) public returns (uint) {\n\t\t_struct.error = x;\n\t\treturn _struct.error;\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"f8a8fd6d\"\n// g(uint256): 7 -> 7\n" + }, + "invalid_enum_compared.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_eq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled == garbled;\n }\n\n function test_eq_ok() public returns (bool) {\n X garbled = X.A;\n return garbled == garbled;\n }\n\n function test_neq() public returns (bool) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled != garbled;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_eq_ok() -> 1\n// test_eq() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_neq() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "revert.sol": { + "content": "contract C {\n uint256 public a = 42;\n\n function f() public {\n a = 1;\n revert();\n }\n\n function g() public {\n a = 1;\n assembly {\n revert(0, 0)\n }\n }\n}\n// ----\n// f() -> FAILURE\n// a() -> 42\n// g() -> FAILURE\n// a() -> 42\n" + }, + "revert_return_area.sol": { + "content": "contract C {\n fallback() external {\n revert(\"abc\");\n }\n\n function f() public returns (uint s, uint r) {\n address x = address(this);\n assembly {\n mstore(0, 7)\n s := call(sub(0, 1), x, 0, 0, 0, 0, 32)\n r := mload(0)\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000\n" + }, + "invalid_instruction.sol": { + "content": "contract C {\n function f() public {\n assembly {\n invalid()\n }\n }\n}\n// ----\n// f() -> FAILURE\n" + }, + "invalid_enum_as_external_arg.sol": { + "content": "contract C {\n enum X {A, B}\n\n function tested(X x) public returns (uint256) {\n return 1;\n }\n\n function test() public returns (uint256) {\n X garbled;\n\n assembly {\n garbled := 5\n }\n\n return this.tested(garbled);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test() -> FAILURE, hex\"4e487b71\", 0x21 # should throw #\n" + }, + "invalid_enum_as_external_ret.sol": { + "content": "contract C {\n enum X {A, B}\n\n function test_return() public returns (X) {\n X garbled;\n assembly {\n garbled := 5\n }\n return garbled;\n }\n\n function test_inline_assignment() public returns (X _ret) {\n assembly {\n _ret := 5\n }\n }\n\n function test_assignment() public returns (X _ret) {\n X tmp;\n assembly {\n tmp := 5\n }\n _ret = tmp;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// test_return() -> FAILURE, hex\"4e487b71\", 33 # both should throw #\n// test_inline_assignment() -> FAILURE, hex\"4e487b71\", 33\n// test_assignment() -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assert_require.sol": { + "content": "contract C {\n function f() public {\n assert(false);\n }\n\n function g(bool val) public returns (bool) {\n assert(val == true);\n return true;\n }\n\n function h(bool val) public returns (bool) {\n require(val);\n return true;\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x01\n// g(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// g(bool): true -> true\n// h(bool): false -> FAILURE\n// h(bool): true -> true\n" + }, + "simple_throw.sol": { + "content": "contract Test {\n function f(uint256 x) public returns (uint256) {\n if (x > 10) return x + 10;\n else revert();\n return 2;\n }\n}\n// ----\n// f(uint256): 11 -> 21\n// f(uint256): 1 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/salted_create_prediction_example/prediction_example.sol b/examples/test/semanticTests/salted_create_prediction_example/prediction_example.sol new file mode 100644 index 00000000..7d0e3c8b --- /dev/null +++ b/examples/test/semanticTests/salted_create_prediction_example/prediction_example.sol @@ -0,0 +1,30 @@ +contract D { + uint public x; + constructor(uint a) { + x = a; + } +} + +contract C { + function createDSalted(bytes32 salt, uint arg) public { + address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked( + bytes1(0xff), + address(this), + salt, + keccak256(abi.encodePacked( + type(D).creationCode, + arg + )) + ))))); + + D d = new D{salt: salt}(arg); + require(address(d) == predictedAddress, "Address mismatch."); + } +} +// ==== +// EVMVersion: >=constantinople +// compileViaYul: also +// ---- +// createDSalted(bytes32,uint256): 42, 64 -> +// gas legacy: 78573 +// gas legacy code: 23600 diff --git a/examples/test/semanticTests/salted_create_prediction_example/prediction_example_standard_input.json b/examples/test/semanticTests/salted_create_prediction_example/prediction_example_standard_input.json new file mode 100644 index 00000000..4ed9c655 --- /dev/null +++ b/examples/test/semanticTests/salted_create_prediction_example/prediction_example_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "salted_create.sol": { + "content": "contract B\n{\n}\n\ncontract A {\n function different_salt() public returns (bool) {\n B x = new B{salt: \"abc\"}();\n B y = new B{salt: \"abcef\"}();\n return x != y;\n }\n function same_salt() public returns (bool) {\n B x = new B{salt: \"xyz\"}();\n try new B{salt: \"xyz\"}() {} catch {\n return true;\n }\n return false;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// different_salt() -> true\n// same_salt() -> true\n// gas irOptimized: 98438295\n// gas irOptimized code: 600\n// gas legacy: 98437509\n// gas legacy code: 1600\n// gas legacyOptimized: 98437367\n// gas legacyOptimized code: 1600\n" + }, + "salted_create_with_value.sol": { + "content": "contract B\n{\n uint x;\n function getBalance() public view returns (uint) {\n return address(this).balance * 1000 + x;\n }\n constructor(uint _x) payable {\n x = _x;\n }\n}\n\ncontract A {\n function f() public payable returns (uint, uint, uint) {\n B x = new B{salt: \"abc\", value: 3}(7);\n B y = new B{value: 3, salt: \"abc\"}(8);\n B z = new B{salt: \"abc\", value: 3}(9);\n return (x.getBalance(), y.getBalance(), z.getBalance());\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(), 10 ether -> 3007, 3008, 3009\n// gas irOptimized: 187022\n// gas irOptimized code: 67200\n// gas legacy: 190858\n// gas legacy code: 190200\n// gas legacyOptimized: 187256\n// gas legacyOptimized code: 92400\n" + }, + "prediction_example.sol": { + "content": "contract D {\n uint public x;\n constructor(uint a) {\n x = a;\n }\n}\n\ncontract C {\n function createDSalted(bytes32 salt, uint arg) public {\n address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n salt,\n keccak256(abi.encodePacked(\n type(D).creationCode,\n arg\n ))\n )))));\n\n D d = new D{salt: salt}(arg);\n require(address(d) == predictedAddress, \"Address mismatch.\");\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// compileViaYul: also\n// ----\n// createDSalted(bytes32,uint256): 42, 64 ->\n// gas legacy: 78573\n// gas legacy code: 23600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/salted_create_salted_create/salted_create.sol b/examples/test/semanticTests/salted_create_salted_create/salted_create.sol new file mode 100644 index 00000000..535a2813 --- /dev/null +++ b/examples/test/semanticTests/salted_create_salted_create/salted_create.sol @@ -0,0 +1,29 @@ +contract B +{ +} + +contract A { + function different_salt() public returns (bool) { + B x = new B{salt: "abc"}(); + B y = new B{salt: "abcef"}(); + return x != y; + } + function same_salt() public returns (bool) { + B x = new B{salt: "xyz"}(); + try new B{salt: "xyz"}() {} catch { + return true; + } + return false; + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// different_salt() -> true +// same_salt() -> true +// gas irOptimized: 98438295 +// gas irOptimized code: 600 +// gas legacy: 98437509 +// gas legacy code: 1600 +// gas legacyOptimized: 98437367 +// gas legacyOptimized code: 1600 diff --git a/examples/test/semanticTests/salted_create_salted_create/salted_create_standard_input.json b/examples/test/semanticTests/salted_create_salted_create/salted_create_standard_input.json new file mode 100644 index 00000000..2fa793de --- /dev/null +++ b/examples/test/semanticTests/salted_create_salted_create/salted_create_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "salted_create.sol": { + "content": "contract B\n{\n}\n\ncontract A {\n function different_salt() public returns (bool) {\n B x = new B{salt: \"abc\"}();\n B y = new B{salt: \"abcef\"}();\n return x != y;\n }\n function same_salt() public returns (bool) {\n B x = new B{salt: \"xyz\"}();\n try new B{salt: \"xyz\"}() {} catch {\n return true;\n }\n return false;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// different_salt() -> true\n// same_salt() -> true\n// gas irOptimized: 98438295\n// gas irOptimized code: 600\n// gas legacy: 98437509\n// gas legacy code: 1600\n// gas legacyOptimized: 98437367\n// gas legacyOptimized code: 1600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value.sol b/examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value.sol new file mode 100644 index 00000000..25d19357 --- /dev/null +++ b/examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value.sol @@ -0,0 +1,29 @@ +contract B +{ + uint x; + function getBalance() public view returns (uint) { + return address(this).balance * 1000 + x; + } + constructor(uint _x) payable { + x = _x; + } +} + +contract A { + function f() public payable returns (uint, uint, uint) { + B x = new B{salt: "abc", value: 3}(7); + B y = new B{value: 3, salt: "abc"}(8); + B z = new B{salt: "abc", value: 3}(9); + return (x.getBalance(), y.getBalance(), z.getBalance()); + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// f(), 10 ether -> 3007, 3008, 3009 +// gas irOptimized: 187022 +// gas irOptimized code: 67200 +// gas legacy: 190858 +// gas legacy code: 190200 +// gas legacyOptimized: 187256 +// gas legacyOptimized code: 92400 diff --git a/examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value_standard_input.json b/examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value_standard_input.json new file mode 100644 index 00000000..f6ec1b05 --- /dev/null +++ b/examples/test/semanticTests/salted_create_salted_create_with_value/salted_create_with_value_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "salted_create.sol": { + "content": "contract B\n{\n}\n\ncontract A {\n function different_salt() public returns (bool) {\n B x = new B{salt: \"abc\"}();\n B y = new B{salt: \"abcef\"}();\n return x != y;\n }\n function same_salt() public returns (bool) {\n B x = new B{salt: \"xyz\"}();\n try new B{salt: \"xyz\"}() {} catch {\n return true;\n }\n return false;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// different_salt() -> true\n// same_salt() -> true\n// gas irOptimized: 98438295\n// gas irOptimized code: 600\n// gas legacy: 98437509\n// gas legacy code: 1600\n// gas legacyOptimized: 98437367\n// gas legacyOptimized code: 1600\n" + }, + "salted_create_with_value.sol": { + "content": "contract B\n{\n uint x;\n function getBalance() public view returns (uint) {\n return address(this).balance * 1000 + x;\n }\n constructor(uint _x) payable {\n x = _x;\n }\n}\n\ncontract A {\n function f() public payable returns (uint, uint, uint) {\n B x = new B{salt: \"abc\", value: 3}(7);\n B y = new B{value: 3, salt: \"abc\"}(8);\n B z = new B{salt: \"abc\", value: 3}(9);\n return (x.getBalance(), y.getBalance(), z.getBalance());\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f(), 10 ether -> 3007, 3008, 3009\n// gas irOptimized: 187022\n// gas irOptimized code: 67200\n// gas legacy: 190858\n// gas legacy code: 190200\n// gas legacyOptimized: 187256\n// gas legacyOptimized code: 92400\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/shanghai_evmone_support/evmone_support.sol b/examples/test/semanticTests/shanghai_evmone_support/evmone_support.sol new file mode 100644 index 00000000..359dc516 --- /dev/null +++ b/examples/test/semanticTests/shanghai_evmone_support/evmone_support.sol @@ -0,0 +1,31 @@ +contract ShortReturn { + constructor() { + assembly { + // return(0, 32) + // PUSH1 0x20 PUSH0 RETURN + mstore(0, hex"60205ff3") + return(0, 4) + } + } +} + +interface DoesItReturnZero { + function foo() external pure returns (uint256); +} + +contract Test { + ShortReturn immutable shortReturn = new ShortReturn(); + function bytecode() external view returns(bytes memory) { + return address(shortReturn).code; + } + function isPush0Supported() external view returns (bool) { + assert(DoesItReturnZero(address(shortReturn)).foo() == 0); + return true; + } +} +// ==== +// compileViaYul: also +// EVMVersion: >=shanghai +// ---- +// bytecode() -> 0x20, 4, 0x60205ff300000000000000000000000000000000000000000000000000000000 +// isPush0Supported() -> true diff --git a/examples/test/semanticTests/shanghai_evmone_support/evmone_support_standard_input.json b/examples/test/semanticTests/shanghai_evmone_support/evmone_support_standard_input.json new file mode 100644 index 00000000..4f50fa62 --- /dev/null +++ b/examples/test/semanticTests/shanghai_evmone_support/evmone_support_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "push0.sol": { + "content": "contract C {\n function zero() external returns (uint) {\n return 0;\n }\n\n}\n// ====\n// compileViaYul: also\n// EVMVersion: >=shanghai\n// ----\n// zero() -> 0\n" + }, + "evmone_support.sol": { + "content": "contract ShortReturn {\n constructor() {\n assembly {\n // return(0, 32)\n // PUSH1 0x20 PUSH0 RETURN\n mstore(0, hex\"60205ff3\")\n return(0, 4)\n }\n }\n}\n\ninterface DoesItReturnZero {\n function foo() external pure returns (uint256);\n}\n\ncontract Test {\n ShortReturn immutable shortReturn = new ShortReturn();\n function bytecode() external view returns(bytes memory) {\n return address(shortReturn).code;\n }\n function isPush0Supported() external view returns (bool) {\n assert(DoesItReturnZero(address(shortReturn)).foo() == 0);\n return true;\n }\n}\n// ====\n// compileViaYul: also\n// EVMVersion: >=shanghai\n// ----\n// bytecode() -> 0x20, 4, 0x60205ff300000000000000000000000000000000000000000000000000000000\n// isPush0Supported() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/shanghai_push0/push0.sol b/examples/test/semanticTests/shanghai_push0/push0.sol new file mode 100644 index 00000000..e1acaaae --- /dev/null +++ b/examples/test/semanticTests/shanghai_push0/push0.sol @@ -0,0 +1,11 @@ +contract C { + function zero() external returns (uint) { + return 0; + } + +} +// ==== +// compileViaYul: also +// EVMVersion: >=shanghai +// ---- +// zero() -> 0 diff --git a/examples/test/semanticTests/shanghai_push0/push0_standard_input.json b/examples/test/semanticTests/shanghai_push0/push0_standard_input.json new file mode 100644 index 00000000..f050aae3 --- /dev/null +++ b/examples/test/semanticTests/shanghai_push0/push0_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "push0.sol": { + "content": "contract C {\n function zero() external returns (uint) {\n return 0;\n }\n\n}\n// ====\n// compileViaYul: also\n// EVMVersion: >=shanghai\n// ----\n// zero() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_alignment/alignment.sol b/examples/test/semanticTests/smoke_alignment/alignment.sol new file mode 100644 index 00000000..296ae016 --- /dev/null +++ b/examples/test/semanticTests/smoke_alignment/alignment.sol @@ -0,0 +1,30 @@ +contract C { + uint256 public stateDecimal = 0x20; +} + +contract D { + bool public stateBool = true; + uint256 public stateDecimal = 42; + bytes32 public stateBytes = "\x42\x00\xef"; + + function internalStateDecimal() public returns (uint256) { + return (new C()).stateDecimal(); + } + + function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) { + stateBool = _bool; + stateDecimal = _decimal; + stateBytes = _bytes; + return (stateBool, stateDecimal, stateBytes); + } +} +// ---- +// stateBool() -> true +// stateBool() -> right(true) +// stateDecimal() -> 42 +// stateDecimal() -> right(42) +// stateBytes() -> left(0x4200ef) +// internalStateDecimal() -> 0x20 +// gas legacy: 76665 +// gas legacy code: 23600 +// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef) diff --git a/examples/test/semanticTests/smoke_alignment/alignment_standard_input.json b/examples/test/semanticTests/smoke_alignment/alignment_standard_input.json new file mode 100644 index 00000000..d059cd21 --- /dev/null +++ b/examples/test/semanticTests/smoke_alignment/alignment_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_arrays/arrays.sol b/examples/test/semanticTests/smoke_arrays/arrays.sol new file mode 100644 index 00000000..404c7157 --- /dev/null +++ b/examples/test/semanticTests/smoke_arrays/arrays.sol @@ -0,0 +1,43 @@ +pragma abicoder v2; + +contract C { + struct T { + uint a; + uint b; + string s; + } + bool[2][] flags; + function r() public returns (bool[3] memory) { + return [true, false, true]; + } + function s() public returns (uint[2] memory, uint) { + return ([uint(123), 456], 789); + } + function u() public returns (T[2] memory) { + return [T(23, 42, "any"), T(555, 666, "any")]; + } + function v() public returns (bool[2][] memory) { + return flags; + } + function w1() public returns (string[1] memory) { + return ["any"]; + } + function w2() public returns (string[2] memory) { + return ["any", "any"]; + } + function w3() public returns (string[3] memory) { + return ["any", "any", "any"]; + } + function x() public returns (string[2] memory, string[3] memory) { + return (["any", "any"], ["any", "any", "any"]); + } +} +// ---- +// r() -> true, false, true +// s() -> 123, 456, 789 +// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, "any", 555, 666, 0x60, 3, "any" +// v() -> 0x20, 0 +// w1() -> 0x20, 0x20, 3, "any" +// w2() -> 0x20, 0x40, 0x80, 3, "any", 3, "any" +// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, "any", 3, "any", 3, "any" +// x() -> 0x40, 0x0100, 0x40, 0x80, 3, "any", 3, "any", 0x60, 0xa0, 0xe0, 3, "any", 3, "any", 3, "any" diff --git a/examples/test/semanticTests/smoke_arrays/arrays_standard_input.json b/examples/test/semanticTests/smoke_arrays/arrays_standard_input.json new file mode 100644 index 00000000..901397ee --- /dev/null +++ b/examples/test/semanticTests/smoke_arrays/arrays_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + }, + "arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct T {\n uint a;\n uint b;\n string s;\n }\n bool[2][] flags;\n function r() public returns (bool[3] memory) {\n return [true, false, true];\n }\n function s() public returns (uint[2] memory, uint) {\n return ([uint(123), 456], 789);\n }\n function u() public returns (T[2] memory) {\n return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n }\n function v() public returns (bool[2][] memory) {\n return flags;\n }\n function w1() public returns (string[1] memory) {\n return [\"any\"];\n }\n function w2() public returns (string[2] memory) {\n return [\"any\", \"any\"];\n }\n function w3() public returns (string[3] memory) {\n return [\"any\", \"any\", \"any\"];\n }\n function x() public returns (string[2] memory, string[3] memory) {\n return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_basic/basic.sol b/examples/test/semanticTests/smoke_basic/basic.sol new file mode 100644 index 00000000..8f05c426 --- /dev/null +++ b/examples/test/semanticTests/smoke_basic/basic.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; + +contract C { + function d() public { + } + function e() public payable returns (uint) { + return msg.value; + } + function f(uint a) public pure returns (uint, uint) { + return (a, a); + } + function g() public pure returns (uint, uint) { + return (2, 3); + } + function h(uint x, uint y) public pure returns (uint) { + unchecked { return x - y; } + } + function i(bool b) public pure returns (bool) { + return !b; + } + function j(bytes32 b) public pure returns (bytes32, bytes32) { + return (b, b); + } + function k() public pure returns (uint) { + return msg.data.length; + } + function l(uint a) public pure returns (uint d) { + return a * 7; + } +} +// ---- +// d() -> +// e(), 1 wei -> 1 +// e(), 1 ether -> 1000000000000000000 +// f(uint256): 3 -> 3, 3 +// g() -> 2, 3 +// h(uint256,uint256): 1, -2 -> 3 +// i(bool): true -> false +// j(bytes32): 0x10001 -> 0x10001, 0x10001 +// k(): hex"4200efef" -> 8 +// l(uint256): 99 -> 693 diff --git a/examples/test/semanticTests/smoke_basic/basic_standard_input.json b/examples/test/semanticTests/smoke_basic/basic_standard_input.json new file mode 100644 index 00000000..9873f1b1 --- /dev/null +++ b/examples/test/semanticTests/smoke_basic/basic_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + }, + "arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct T {\n uint a;\n uint b;\n string s;\n }\n bool[2][] flags;\n function r() public returns (bool[3] memory) {\n return [true, false, true];\n }\n function s() public returns (uint[2] memory, uint) {\n return ([uint(123), 456], 789);\n }\n function u() public returns (T[2] memory) {\n return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n }\n function v() public returns (bool[2][] memory) {\n return flags;\n }\n function w1() public returns (string[1] memory) {\n return [\"any\"];\n }\n function w2() public returns (string[2] memory) {\n return [\"any\", \"any\"];\n }\n function w3() public returns (string[3] memory) {\n return [\"any\", \"any\", \"any\"];\n }\n function x() public returns (string[2] memory, string[3] memory) {\n return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n" + }, + "constructor.sol": { + "content": "contract C {\n uint public state = 0;\n constructor(uint _state) payable {\n state = _state;\n }\n function balance() public payable returns (uint256) {\n return address(this).balance;\n }\n function update(uint _state) public {\n state = _state;\n }\n}\n// ----\n// constructor(), 2 wei: 3 ->\n// gas irOptimized: 78996\n// gas irOptimized code: 25400\n// gas legacy: 83055\n// gas legacy code: 65200\n// gas legacyOptimized: 78898\n// gas legacyOptimized code: 27800\n// state() -> 3\n// balance() -> 2\n// balance -> 2\n// update(uint256): 4\n// state() -> 4\n" + }, + "basic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function d() public {\n }\n function e() public payable returns (uint) {\n return msg.value;\n }\n function f(uint a) public pure returns (uint, uint) {\n return (a, a);\n }\n function g() public pure returns (uint, uint) {\n return (2, 3);\n }\n function h(uint x, uint y) public pure returns (uint) {\n unchecked { return x - y; }\n }\n function i(bool b) public pure returns (bool) {\n return !b;\n }\n function j(bytes32 b) public pure returns (bytes32, bytes32) {\n return (b, b);\n }\n function k() public pure returns (uint) {\n return msg.data.length;\n }\n function l(uint a) public pure returns (uint d) {\n return a * 7;\n }\n}\n// ----\n// d() ->\n// e(), 1 wei -> 1\n// e(), 1 ether -> 1000000000000000000\n// f(uint256): 3 -> 3, 3\n// g() -> 2, 3\n// h(uint256,uint256): 1, -2 -> 3\n// i(bool): true -> false\n// j(bytes32): 0x10001 -> 0x10001, 0x10001\n// k(): hex\"4200efef\" -> 8\n// l(uint256): 99 -> 693\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings.sol b/examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings.sol new file mode 100644 index 00000000..c20dd919 --- /dev/null +++ b/examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings.sol @@ -0,0 +1,21 @@ +contract C { + function e(bytes memory b) public pure returns (bytes memory) { + return b; + } + function f() public pure returns (string memory, string memory) { + return ("any", "any"); + } + function g() public pure returns (string memory, uint, string memory) { + return ("any", 42, "any"); + } + function h() public pure returns (string memory) { + return "any"; + } +} +// ---- +// e(bytes): 32, 3, hex"AB33BB" -> 32, 3, left(0xAB33BB) +// e(bytes): 32, 32, 0x20 -> 32, 32, 0x20 +// e(bytes): 32, 3, hex"AB33FF" -> 32, 3, hex"ab33ff0000000000000000000000000000000000000000000000000000000000" +// f() -> 0x40, 0x80, 3, "any", 3, "any" +// g() -> 0x60, 0x2a, 0xa0, 3, "any", 3, "any" +// h() -> 0x20, 3, "any" diff --git a/examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings_standard_input.json b/examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings_standard_input.json new file mode 100644 index 00000000..d14a3a87 --- /dev/null +++ b/examples/test/semanticTests/smoke_bytes_and_strings/bytes_and_strings_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + }, + "arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct T {\n uint a;\n uint b;\n string s;\n }\n bool[2][] flags;\n function r() public returns (bool[3] memory) {\n return [true, false, true];\n }\n function s() public returns (uint[2] memory, uint) {\n return ([uint(123), 456], 789);\n }\n function u() public returns (T[2] memory) {\n return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n }\n function v() public returns (bool[2][] memory) {\n return flags;\n }\n function w1() public returns (string[1] memory) {\n return [\"any\"];\n }\n function w2() public returns (string[2] memory) {\n return [\"any\", \"any\"];\n }\n function w3() public returns (string[3] memory) {\n return [\"any\", \"any\", \"any\"];\n }\n function x() public returns (string[2] memory, string[3] memory) {\n return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n" + }, + "constructor.sol": { + "content": "contract C {\n uint public state = 0;\n constructor(uint _state) payable {\n state = _state;\n }\n function balance() public payable returns (uint256) {\n return address(this).balance;\n }\n function update(uint _state) public {\n state = _state;\n }\n}\n// ----\n// constructor(), 2 wei: 3 ->\n// gas irOptimized: 78996\n// gas irOptimized code: 25400\n// gas legacy: 83055\n// gas legacy code: 65200\n// gas legacyOptimized: 78898\n// gas legacyOptimized code: 27800\n// state() -> 3\n// balance() -> 2\n// balance -> 2\n// update(uint256): 4\n// state() -> 4\n" + }, + "basic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function d() public {\n }\n function e() public payable returns (uint) {\n return msg.value;\n }\n function f(uint a) public pure returns (uint, uint) {\n return (a, a);\n }\n function g() public pure returns (uint, uint) {\n return (2, 3);\n }\n function h(uint x, uint y) public pure returns (uint) {\n unchecked { return x - y; }\n }\n function i(bool b) public pure returns (bool) {\n return !b;\n }\n function j(bytes32 b) public pure returns (bytes32, bytes32) {\n return (b, b);\n }\n function k() public pure returns (uint) {\n return msg.data.length;\n }\n function l(uint a) public pure returns (uint d) {\n return a * 7;\n }\n}\n// ----\n// d() ->\n// e(), 1 wei -> 1\n// e(), 1 ether -> 1000000000000000000\n// f(uint256): 3 -> 3, 3\n// g() -> 2, 3\n// h(uint256,uint256): 1, -2 -> 3\n// i(bool): true -> false\n// j(bytes32): 0x10001 -> 0x10001, 0x10001\n// k(): hex\"4200efef\" -> 8\n// l(uint256): 99 -> 693\n" + }, + "fallback.sol": { + "content": "contract A {\n uint public data;\n uint public balance;\n bytes public externalData;\n fallback() external payable {\n data += 1;\n balance = msg.value;\n externalData = msg.data;\n }\n}\n// ----\n// data() -> 0\n// ()\n// data() -> 1\n// (): hex\"42ef\"\n// data() -> 2\n// externalData() -> 0x20, 2, left(0x42ef)\n// balance() -> 0\n// (), 1 wei\n// balance() -> 1\n// (), 2 wei: hex\"fefe\"\n// balance() -> 2\n// externalData() -> 0x20, 2, left(0xfefe)\n" + }, + "bytes_and_strings.sol": { + "content": "contract C {\n function e(bytes memory b) public pure returns (bytes memory) {\n return b;\n }\n function f() public pure returns (string memory, string memory) {\n return (\"any\", \"any\");\n }\n function g() public pure returns (string memory, uint, string memory) {\n return (\"any\", 42, \"any\");\n }\n function h() public pure returns (string memory) {\n return \"any\";\n }\n}\n// ----\n// e(bytes): 32, 3, hex\"AB33BB\" -> 32, 3, left(0xAB33BB)\n// e(bytes): 32, 32, 0x20 -> 32, 32, 0x20\n// e(bytes): 32, 3, hex\"AB33FF\" -> 32, 3, hex\"ab33ff0000000000000000000000000000000000000000000000000000000000\"\n// f() -> 0x40, 0x80, 3, \"any\", 3, \"any\"\n// g() -> 0x60, 0x2a, 0xa0, 3, \"any\", 3, \"any\"\n// h() -> 0x20, 3, \"any\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_constructor/constructor.sol b/examples/test/semanticTests/smoke_constructor/constructor.sol new file mode 100644 index 00000000..d5c5280a --- /dev/null +++ b/examples/test/semanticTests/smoke_constructor/constructor.sol @@ -0,0 +1,25 @@ +contract C { + uint public state = 0; + constructor(uint _state) payable { + state = _state; + } + function balance() public payable returns (uint256) { + return address(this).balance; + } + function update(uint _state) public { + state = _state; + } +} +// ---- +// constructor(), 2 wei: 3 -> +// gas irOptimized: 78996 +// gas irOptimized code: 25400 +// gas legacy: 83055 +// gas legacy code: 65200 +// gas legacyOptimized: 78898 +// gas legacyOptimized code: 27800 +// state() -> 3 +// balance() -> 2 +// balance -> 2 +// update(uint256): 4 +// state() -> 4 diff --git a/examples/test/semanticTests/smoke_constructor/constructor_standard_input.json b/examples/test/semanticTests/smoke_constructor/constructor_standard_input.json new file mode 100644 index 00000000..eb664a9e --- /dev/null +++ b/examples/test/semanticTests/smoke_constructor/constructor_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + }, + "arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct T {\n uint a;\n uint b;\n string s;\n }\n bool[2][] flags;\n function r() public returns (bool[3] memory) {\n return [true, false, true];\n }\n function s() public returns (uint[2] memory, uint) {\n return ([uint(123), 456], 789);\n }\n function u() public returns (T[2] memory) {\n return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n }\n function v() public returns (bool[2][] memory) {\n return flags;\n }\n function w1() public returns (string[1] memory) {\n return [\"any\"];\n }\n function w2() public returns (string[2] memory) {\n return [\"any\", \"any\"];\n }\n function w3() public returns (string[3] memory) {\n return [\"any\", \"any\", \"any\"];\n }\n function x() public returns (string[2] memory, string[3] memory) {\n return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n" + }, + "constructor.sol": { + "content": "contract C {\n uint public state = 0;\n constructor(uint _state) payable {\n state = _state;\n }\n function balance() public payable returns (uint256) {\n return address(this).balance;\n }\n function update(uint _state) public {\n state = _state;\n }\n}\n// ----\n// constructor(), 2 wei: 3 ->\n// gas irOptimized: 78996\n// gas irOptimized code: 25400\n// gas legacy: 83055\n// gas legacy code: 65200\n// gas legacyOptimized: 78898\n// gas legacyOptimized code: 27800\n// state() -> 3\n// balance() -> 2\n// balance -> 2\n// update(uint256): 4\n// state() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_failure/failure.sol b/examples/test/semanticTests/smoke_failure/failure.sol new file mode 100644 index 00000000..14cf1e62 --- /dev/null +++ b/examples/test/semanticTests/smoke_failure/failure.sol @@ -0,0 +1,24 @@ +contract C { + function e() public pure { + revert("Transaction failed."); + } + function f(bool _value) public pure { + string memory message; + require(_value, message); + } + function g(bool _value) public pure { + require(_value, "Value is false."); + } + function h() public pure returns (uint) { + assert(false); + } +} +// ==== +// EVMVersion: >homestead +// allowNonExistingFunctions: true +// ---- +// _() -> FAILURE +// e() -> FAILURE, hex"08c379a0", 0x20, 0x13, "Transaction failed." +// f(bool): false -> FAILURE, hex"08c379a0", 0x20, 0x00 +// g(bool): false -> FAILURE, hex"08c379a0", 0x20, 0x0f, "Value is false." +// h() -> FAILURE, hex"4e487b71", 0x01 diff --git a/examples/test/semanticTests/smoke_failure/failure_standard_input.json b/examples/test/semanticTests/smoke_failure/failure_standard_input.json new file mode 100644 index 00000000..7b0af861 --- /dev/null +++ b/examples/test/semanticTests/smoke_failure/failure_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + }, + "arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct T {\n uint a;\n uint b;\n string s;\n }\n bool[2][] flags;\n function r() public returns (bool[3] memory) {\n return [true, false, true];\n }\n function s() public returns (uint[2] memory, uint) {\n return ([uint(123), 456], 789);\n }\n function u() public returns (T[2] memory) {\n return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n }\n function v() public returns (bool[2][] memory) {\n return flags;\n }\n function w1() public returns (string[1] memory) {\n return [\"any\"];\n }\n function w2() public returns (string[2] memory) {\n return [\"any\", \"any\"];\n }\n function w3() public returns (string[3] memory) {\n return [\"any\", \"any\", \"any\"];\n }\n function x() public returns (string[2] memory, string[3] memory) {\n return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n" + }, + "constructor.sol": { + "content": "contract C {\n uint public state = 0;\n constructor(uint _state) payable {\n state = _state;\n }\n function balance() public payable returns (uint256) {\n return address(this).balance;\n }\n function update(uint _state) public {\n state = _state;\n }\n}\n// ----\n// constructor(), 2 wei: 3 ->\n// gas irOptimized: 78996\n// gas irOptimized code: 25400\n// gas legacy: 83055\n// gas legacy code: 65200\n// gas legacyOptimized: 78898\n// gas legacyOptimized code: 27800\n// state() -> 3\n// balance() -> 2\n// balance -> 2\n// update(uint256): 4\n// state() -> 4\n" + }, + "basic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function d() public {\n }\n function e() public payable returns (uint) {\n return msg.value;\n }\n function f(uint a) public pure returns (uint, uint) {\n return (a, a);\n }\n function g() public pure returns (uint, uint) {\n return (2, 3);\n }\n function h(uint x, uint y) public pure returns (uint) {\n unchecked { return x - y; }\n }\n function i(bool b) public pure returns (bool) {\n return !b;\n }\n function j(bytes32 b) public pure returns (bytes32, bytes32) {\n return (b, b);\n }\n function k() public pure returns (uint) {\n return msg.data.length;\n }\n function l(uint a) public pure returns (uint d) {\n return a * 7;\n }\n}\n// ----\n// d() ->\n// e(), 1 wei -> 1\n// e(), 1 ether -> 1000000000000000000\n// f(uint256): 3 -> 3, 3\n// g() -> 2, 3\n// h(uint256,uint256): 1, -2 -> 3\n// i(bool): true -> false\n// j(bytes32): 0x10001 -> 0x10001, 0x10001\n// k(): hex\"4200efef\" -> 8\n// l(uint256): 99 -> 693\n" + }, + "fallback.sol": { + "content": "contract A {\n uint public data;\n uint public balance;\n bytes public externalData;\n fallback() external payable {\n data += 1;\n balance = msg.value;\n externalData = msg.data;\n }\n}\n// ----\n// data() -> 0\n// ()\n// data() -> 1\n// (): hex\"42ef\"\n// data() -> 2\n// externalData() -> 0x20, 2, left(0x42ef)\n// balance() -> 0\n// (), 1 wei\n// balance() -> 1\n// (), 2 wei: hex\"fefe\"\n// balance() -> 2\n// externalData() -> 0x20, 2, left(0xfefe)\n" + }, + "bytes_and_strings.sol": { + "content": "contract C {\n function e(bytes memory b) public pure returns (bytes memory) {\n return b;\n }\n function f() public pure returns (string memory, string memory) {\n return (\"any\", \"any\");\n }\n function g() public pure returns (string memory, uint, string memory) {\n return (\"any\", 42, \"any\");\n }\n function h() public pure returns (string memory) {\n return \"any\";\n }\n}\n// ----\n// e(bytes): 32, 3, hex\"AB33BB\" -> 32, 3, left(0xAB33BB)\n// e(bytes): 32, 32, 0x20 -> 32, 32, 0x20\n// e(bytes): 32, 3, hex\"AB33FF\" -> 32, 3, hex\"ab33ff0000000000000000000000000000000000000000000000000000000000\"\n// f() -> 0x40, 0x80, 3, \"any\", 3, \"any\"\n// g() -> 0x60, 0x2a, 0xa0, 3, \"any\", 3, \"any\"\n// h() -> 0x20, 3, \"any\"\n" + }, + "failure.sol": { + "content": "contract C {\n function e() public pure {\n revert(\"Transaction failed.\");\n }\n function f(bool _value) public pure {\n string memory message;\n require(_value, message);\n }\n function g(bool _value) public pure {\n require(_value, \"Value is false.\");\n }\n function h() public pure returns (uint) {\n assert(false);\n }\n}\n// ====\n// EVMVersion: >homestead\n// allowNonExistingFunctions: true\n// ----\n// _() -> FAILURE\n// e() -> FAILURE, hex\"08c379a0\", 0x20, 0x13, \"Transaction failed.\"\n// f(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x00\n// g(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0x0f, \"Value is false.\"\n// h() -> FAILURE, hex\"4e487b71\", 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_fallback/fallback.sol b/examples/test/semanticTests/smoke_fallback/fallback.sol new file mode 100644 index 00000000..b0e515db --- /dev/null +++ b/examples/test/semanticTests/smoke_fallback/fallback.sol @@ -0,0 +1,23 @@ +contract A { + uint public data; + uint public balance; + bytes public externalData; + fallback() external payable { + data += 1; + balance = msg.value; + externalData = msg.data; + } +} +// ---- +// data() -> 0 +// () +// data() -> 1 +// (): hex"42ef" +// data() -> 2 +// externalData() -> 0x20, 2, left(0x42ef) +// balance() -> 0 +// (), 1 wei +// balance() -> 1 +// (), 2 wei: hex"fefe" +// balance() -> 2 +// externalData() -> 0x20, 2, left(0xfefe) diff --git a/examples/test/semanticTests/smoke_fallback/fallback_standard_input.json b/examples/test/semanticTests/smoke_fallback/fallback_standard_input.json new file mode 100644 index 00000000..5b1176d8 --- /dev/null +++ b/examples/test/semanticTests/smoke_fallback/fallback_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + }, + "alignment.sol": { + "content": "contract C {\n uint256 public stateDecimal = 0x20;\n}\n\ncontract D {\n bool public stateBool = true;\n uint256 public stateDecimal = 42;\n bytes32 public stateBytes = \"\\x42\\x00\\xef\";\n\n function internalStateDecimal() public returns (uint256) {\n return (new C()).stateDecimal();\n }\n\n function update(bool _bool, uint256 _decimal, bytes32 _bytes) public returns (bool, uint256, bytes32) {\n stateBool = _bool;\n stateDecimal = _decimal;\n stateBytes = _bytes;\n return (stateBool, stateDecimal, stateBytes);\n }\n}\n// ----\n// stateBool() -> true\n// stateBool() -> right(true)\n// stateDecimal() -> 42\n// stateDecimal() -> right(42)\n// stateBytes() -> left(0x4200ef)\n// internalStateDecimal() -> 0x20\n// gas legacy: 76665\n// gas legacy code: 23600\n// update(bool,uint256,bytes32): false, -23, left(0x2300ef) -> false, -23, left(0x2300ef)\n" + }, + "arrays.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct T {\n uint a;\n uint b;\n string s;\n }\n bool[2][] flags;\n function r() public returns (bool[3] memory) {\n return [true, false, true];\n }\n function s() public returns (uint[2] memory, uint) {\n return ([uint(123), 456], 789);\n }\n function u() public returns (T[2] memory) {\n return [T(23, 42, \"any\"), T(555, 666, \"any\")];\n }\n function v() public returns (bool[2][] memory) {\n return flags;\n }\n function w1() public returns (string[1] memory) {\n return [\"any\"];\n }\n function w2() public returns (string[2] memory) {\n return [\"any\", \"any\"];\n }\n function w3() public returns (string[3] memory) {\n return [\"any\", \"any\", \"any\"];\n }\n function x() public returns (string[2] memory, string[3] memory) {\n return ([\"any\", \"any\"], [\"any\", \"any\", \"any\"]);\n }\n}\n// ----\n// r() -> true, false, true\n// s() -> 123, 456, 789\n// u() -> 0x20, 0x40, 0xE0, 23, 42, 0x60, 3, \"any\", 555, 666, 0x60, 3, \"any\"\n// v() -> 0x20, 0\n// w1() -> 0x20, 0x20, 3, \"any\"\n// w2() -> 0x20, 0x40, 0x80, 3, \"any\", 3, \"any\"\n// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n// x() -> 0x40, 0x0100, 0x40, 0x80, 3, \"any\", 3, \"any\", 0x60, 0xa0, 0xe0, 3, \"any\", 3, \"any\", 3, \"any\"\n" + }, + "constructor.sol": { + "content": "contract C {\n uint public state = 0;\n constructor(uint _state) payable {\n state = _state;\n }\n function balance() public payable returns (uint256) {\n return address(this).balance;\n }\n function update(uint _state) public {\n state = _state;\n }\n}\n// ----\n// constructor(), 2 wei: 3 ->\n// gas irOptimized: 78996\n// gas irOptimized code: 25400\n// gas legacy: 83055\n// gas legacy code: 65200\n// gas legacyOptimized: 78898\n// gas legacyOptimized code: 27800\n// state() -> 3\n// balance() -> 2\n// balance -> 2\n// update(uint256): 4\n// state() -> 4\n" + }, + "basic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n function d() public {\n }\n function e() public payable returns (uint) {\n return msg.value;\n }\n function f(uint a) public pure returns (uint, uint) {\n return (a, a);\n }\n function g() public pure returns (uint, uint) {\n return (2, 3);\n }\n function h(uint x, uint y) public pure returns (uint) {\n unchecked { return x - y; }\n }\n function i(bool b) public pure returns (bool) {\n return !b;\n }\n function j(bytes32 b) public pure returns (bytes32, bytes32) {\n return (b, b);\n }\n function k() public pure returns (uint) {\n return msg.data.length;\n }\n function l(uint a) public pure returns (uint d) {\n return a * 7;\n }\n}\n// ----\n// d() ->\n// e(), 1 wei -> 1\n// e(), 1 ether -> 1000000000000000000\n// f(uint256): 3 -> 3, 3\n// g() -> 2, 3\n// h(uint256,uint256): 1, -2 -> 3\n// i(bool): true -> false\n// j(bytes32): 0x10001 -> 0x10001, 0x10001\n// k(): hex\"4200efef\" -> 8\n// l(uint256): 99 -> 693\n" + }, + "fallback.sol": { + "content": "contract A {\n uint public data;\n uint public balance;\n bytes public externalData;\n fallback() external payable {\n data += 1;\n balance = msg.value;\n externalData = msg.data;\n }\n}\n// ----\n// data() -> 0\n// ()\n// data() -> 1\n// (): hex\"42ef\"\n// data() -> 2\n// externalData() -> 0x20, 2, left(0x42ef)\n// balance() -> 0\n// (), 1 wei\n// balance() -> 1\n// (), 2 wei: hex\"fefe\"\n// balance() -> 2\n// externalData() -> 0x20, 2, left(0xfefe)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_multiline/multiline.sol b/examples/test/semanticTests/smoke_multiline/multiline.sol new file mode 100644 index 00000000..624b1947 --- /dev/null +++ b/examples/test/semanticTests/smoke_multiline/multiline.sol @@ -0,0 +1,13 @@ +contract C { + function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) { + return a + b + c + d + e; + } +} +// ==== +// allowNonExistingFunctions: true +// ---- +// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1 +// -> 5 +// g() +// # g() does not exist # +// -> FAILURE diff --git a/examples/test/semanticTests/smoke_multiline/multiline_standard_input.json b/examples/test/semanticTests/smoke_multiline/multiline_standard_input.json new file mode 100644 index 00000000..53f12552 --- /dev/null +++ b/examples/test/semanticTests/smoke_multiline/multiline_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_multiline_comments/multiline_comments.sol b/examples/test/semanticTests/smoke_multiline_comments/multiline_comments.sol new file mode 100644 index 00000000..17de40fc --- /dev/null +++ b/examples/test/semanticTests/smoke_multiline_comments/multiline_comments.sol @@ -0,0 +1,17 @@ +contract C { + function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) { + return a + b + c + d + e; + } +} +// ---- +// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1 +// # A comment on the function parameters. # +// -> 5 +// f(uint256,uint256,uint256,uint256,uint256): +// 1, +// 1, +// 1, +// 1, +// 1 +// -> 5 +// # Should return sum of all parameters. # diff --git a/examples/test/semanticTests/smoke_multiline_comments/multiline_comments_standard_input.json b/examples/test/semanticTests/smoke_multiline_comments/multiline_comments_standard_input.json new file mode 100644 index 00000000..08aec3f5 --- /dev/null +++ b/examples/test/semanticTests/smoke_multiline_comments/multiline_comments_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/smoke_structs/structs.sol b/examples/test/semanticTests/smoke_structs/structs.sol new file mode 100644 index 00000000..d6df382c --- /dev/null +++ b/examples/test/semanticTests/smoke_structs/structs.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +contract C { + struct S { + uint a; + uint b; + } + struct T { + uint a; + uint b; + string s; + } + function s() public returns (S memory) { + return S(23, 42); + } + function t() public returns (T memory) { + return T(23, 42, "any"); + } +} +// ---- +// s() -> 23, 42 +// t() -> 0x20, 23, 42, 0x60, 3, "any" diff --git a/examples/test/semanticTests/smoke_structs/structs_standard_input.json b/examples/test/semanticTests/smoke_structs/structs_standard_input.json new file mode 100644 index 00000000..30a53cc9 --- /dev/null +++ b/examples/test/semanticTests/smoke_structs/structs_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "multiline.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// -> 5\n// g()\n// # g() does not exist #\n// -> FAILURE\n" + }, + "multiline_comments.sol": { + "content": "contract C {\n function f(uint a, uint b, uint c, uint d, uint e) public returns (uint) {\n return a + b + c + d + e;\n }\n}\n// ----\n// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1\n// # A comment on the function parameters. #\n// -> 5\n// f(uint256,uint256,uint256,uint256,uint256):\n// 1,\n// 1,\n// 1,\n// 1,\n// 1\n// -> 5\n// # Should return sum of all parameters. #\n" + }, + "structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint b;\n }\n struct T {\n uint a;\n uint b;\n string s;\n }\n function s() public returns (S memory) {\n return S(23, 42);\n }\n function t() public returns (T memory) {\n return T(23, 42, \"any\");\n }\n}\n// ----\n// s() -> 23, 42\n// t() -> 0x20, 23, 42, 0x60, 3, \"any\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string.sol b/examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string.sol new file mode 100644 index 00000000..80f734a3 --- /dev/null +++ b/examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string.sol @@ -0,0 +1,12 @@ +contract C { + function f() public pure returns (bytes memory r1, bytes memory r2) { + string memory x = "my_signature"; + r1 = abi.encodeWithSignature("my_signature", 1); + r2 = abi.encodeWithSignature(x, 1); + assert(r1.length == r2.length); + for (uint i = 0; i < r1.length; i++) + assert(r1[i] == r2[i]); + } +} +// ---- +// f() -> 0x40, 0xa0, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216 diff --git a/examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string_standard_input.json b/examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string_standard_input.json new file mode 100644 index 00000000..95fbd26c --- /dev/null +++ b/examples/test/semanticTests/specialFunctions_abi_encode_with_signature_from_string/abi_encode_with_signature_from_string_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "abi_encode_with_signature_from_string.sol": { + "content": "contract C {\n function f() public pure returns (bytes memory r1, bytes memory r2) {\n string memory x = \"my_signature\";\n r1 = abi.encodeWithSignature(\"my_signature\", 1);\n r2 = abi.encodeWithSignature(x, 1);\n assert(r1.length == r2.length);\n for (uint i = 0; i < r1.length; i++)\n assert(r1[i] == r2[i]);\n }\n}\n// ----\n// f() -> 0x40, 0xa0, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access.sol b/examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access.sol new file mode 100644 index 00000000..b255b188 --- /dev/null +++ b/examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure { + abi.encode; + abi.encodePacked; + abi.encodeWithSelector; + abi.encodeWithSignature; + abi.decode; + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access_standard_input.json b/examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access_standard_input.json new file mode 100644 index 00000000..b0fde090 --- /dev/null +++ b/examples/test/semanticTests/specialFunctions_abi_functions_member_access/abi_functions_member_access_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "abi_encode_with_signature_from_string.sol": { + "content": "contract C {\n function f() public pure returns (bytes memory r1, bytes memory r2) {\n string memory x = \"my_signature\";\n r1 = abi.encodeWithSignature(\"my_signature\", 1);\n r2 = abi.encodeWithSignature(x, 1);\n assert(r1.length == r2.length);\n for (uint i = 0; i < r1.length; i++)\n assert(r1[i] == r2[i]);\n }\n}\n// ----\n// f() -> 0x40, 0xa0, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "keccak256_optimized.sol": { + "content": "// tests compile-time evaluation of keccak256 on literal strings\ncontract C {\n function short() public pure returns (bool) {\n bytes32 a = keccak256(\"abcdefghijklmn\");\n bytes memory s = \"abcdefghijklmn\";\n return a == keccak256(s);\n }\n bytes32 constant sc = keccak256(\"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\");\n function long() public pure returns (bool, bool) {\n bytes32 a = keccak256(\"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\");\n bytes memory s = \"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\";\n return (a == keccak256(s), sc == keccak256(s));\n }\n}\n// ----\n// short() -> true\n// long() -> true, true\n" + }, + "abi_functions_member_access.sol": { + "content": "contract C {\n function f() public pure {\n abi.encode;\n abi.encodePacked;\n abi.encodeWithSelector;\n abi.encodeWithSignature;\n abi.decode;\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized.sol b/examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized.sol new file mode 100644 index 00000000..6dcb53e2 --- /dev/null +++ b/examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized.sol @@ -0,0 +1,17 @@ +// tests compile-time evaluation of keccak256 on literal strings +contract C { + function short() public pure returns (bool) { + bytes32 a = keccak256("abcdefghijklmn"); + bytes memory s = "abcdefghijklmn"; + return a == keccak256(s); + } + bytes32 constant sc = keccak256("abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn"); + function long() public pure returns (bool, bool) { + bytes32 a = keccak256("abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn"); + bytes memory s = "abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn"; + return (a == keccak256(s), sc == keccak256(s)); + } +} +// ---- +// short() -> true +// long() -> true, true diff --git a/examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized_standard_input.json b/examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized_standard_input.json new file mode 100644 index 00000000..b65ace67 --- /dev/null +++ b/examples/test/semanticTests/specialFunctions_keccak256_optimized/keccak256_optimized_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "abi_encode_with_signature_from_string.sol": { + "content": "contract C {\n function f() public pure returns (bytes memory r1, bytes memory r2) {\n string memory x = \"my_signature\";\n r1 = abi.encodeWithSignature(\"my_signature\", 1);\n r2 = abi.encodeWithSignature(x, 1);\n assert(r1.length == r2.length);\n for (uint i = 0; i < r1.length; i++)\n assert(r1[i] == r2[i]);\n }\n}\n// ----\n// f() -> 0x40, 0xa0, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216, 0x24, -813742827273327954027712588510533233455028711326166692885570228492575965184, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "keccak256_optimized.sol": { + "content": "// tests compile-time evaluation of keccak256 on literal strings\ncontract C {\n function short() public pure returns (bool) {\n bytes32 a = keccak256(\"abcdefghijklmn\");\n bytes memory s = \"abcdefghijklmn\";\n return a == keccak256(s);\n }\n bytes32 constant sc = keccak256(\"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\");\n function long() public pure returns (bool, bool) {\n bytes32 a = keccak256(\"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\");\n bytes memory s = \"abcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmnabcdefghijklmn\";\n return (a == keccak256(s), sc == keccak256(s));\n }\n}\n// ----\n// short() -> true\n// long() -> true, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_blobhash/blobhash.sol b/examples/test/semanticTests/state_blobhash/blobhash.sol new file mode 100644 index 00000000..f27b4072 --- /dev/null +++ b/examples/test/semanticTests/state_blobhash/blobhash.sol @@ -0,0 +1,14 @@ +contract C { + function f(uint _index) public returns (bytes32) { + return blobhash(_index); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001 +// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002 +// f(uint256): 2 -> 0x00 +// f(uint256): 255 -> 0x00 +// f(uint256): 256 -> 0x00 +// f(uint256): 257 -> 0x00 diff --git a/examples/test/semanticTests/state_blobhash/blobhash_standard_input.json b/examples/test/semanticTests/state_blobhash/blobhash_standard_input.json new file mode 100644 index 00000000..dc03f056 --- /dev/null +++ b/examples/test/semanticTests/state_blobhash/blobhash_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f(uint _index) public returns (bytes32) {\n return blobhash(_index);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_basefee/block_basefee.sol b/examples/test/semanticTests/state_block_basefee/block_basefee.sol new file mode 100644 index 00000000..ebeaceec --- /dev/null +++ b/examples/test/semanticTests/state_block_basefee/block_basefee.sol @@ -0,0 +1,17 @@ +contract C { + function f() public view returns (uint) { + return block.basefee; + } + function g() public view returns (uint ret) { + assembly { + ret := basefee() + } + } +} +// ==== +// EVMVersion: >=london +// ---- +// f() -> 7 +// g() -> 7 +// f() -> 7 +// g() -> 7 diff --git a/examples/test/semanticTests/state_block_basefee/block_basefee_standard_input.json b/examples/test/semanticTests/state_block_basefee/block_basefee_standard_input.json new file mode 100644 index 00000000..40e49c6b --- /dev/null +++ b/examples/test/semanticTests/state_block_basefee/block_basefee_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee.sol b/examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee.sol new file mode 100644 index 00000000..23da779e --- /dev/null +++ b/examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee.sol @@ -0,0 +1,17 @@ +contract C { + function f() public view returns (uint) { + return block.blobbasefee; + } + function g() public view returns (uint ret) { + assembly { + ret := blobbasefee() + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1 +// g() -> 1 +// f() -> 1 +// g() -> 1 diff --git a/examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee_standard_input.json b/examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee_standard_input.json new file mode 100644 index 00000000..b2624e8c --- /dev/null +++ b/examples/test/semanticTests/state_block_blobbasefee/block_blobbasefee_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_chainid/block_chainid.sol b/examples/test/semanticTests/state_block_chainid/block_chainid.sol new file mode 100644 index 00000000..5d157323 --- /dev/null +++ b/examples/test/semanticTests/state_block_chainid/block_chainid.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint) { + return block.chainid; + } +} +// ==== +// EVMVersion: >=istanbul +// ---- +// f() -> 1 +// f() -> 1 +// f() -> 1 diff --git a/examples/test/semanticTests/state_block_chainid/block_chainid_standard_input.json b/examples/test/semanticTests/state_block_chainid/block_chainid_standard_input.json new file mode 100644 index 00000000..47bcc9ff --- /dev/null +++ b/examples/test/semanticTests/state_block_chainid/block_chainid_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_coinbase/block_coinbase.sol b/examples/test/semanticTests/state_block_coinbase/block_coinbase.sol new file mode 100644 index 00000000..e7aae2fc --- /dev/null +++ b/examples/test/semanticTests/state_block_coinbase/block_coinbase.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (address payable) { + return block.coinbase; + } +} +// ---- +// f() -> 0x7878787878787878787878787878787878787878 +// f() -> 0x7878787878787878787878787878787878787878 +// f() -> 0x7878787878787878787878787878787878787878 diff --git a/examples/test/semanticTests/state_block_coinbase/block_coinbase_standard_input.json b/examples/test/semanticTests/state_block_coinbase/block_coinbase_standard_input.json new file mode 100644 index 00000000..491391ea --- /dev/null +++ b/examples/test/semanticTests/state_block_coinbase/block_coinbase_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_difficulty/block_difficulty.sol b/examples/test/semanticTests/state_block_difficulty/block_difficulty.sol new file mode 100644 index 00000000..921200dd --- /dev/null +++ b/examples/test/semanticTests/state_block_difficulty/block_difficulty.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint) { + return block.difficulty; + } +} +// ==== +// EVMVersion: 200000000 +// f() -> 200000000 +// f() -> 200000000 diff --git a/examples/test/semanticTests/state_block_difficulty/block_difficulty_standard_input.json b/examples/test/semanticTests/state_block_difficulty/block_difficulty_standard_input.json new file mode 100644 index 00000000..3c0ae095 --- /dev/null +++ b/examples/test/semanticTests/state_block_difficulty/block_difficulty_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris.sol b/examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris.sol new file mode 100644 index 00000000..226a8bbb --- /dev/null +++ b/examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint) { + return block.difficulty; + } +} +// ==== +// EVMVersion: >=paris +// ---- +// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777 +// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777 +// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777 diff --git a/examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris_standard_input.json b/examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris_standard_input.json new file mode 100644 index 00000000..f5c40b5b --- /dev/null +++ b/examples/test/semanticTests/state_block_difficulty_post_paris/block_difficulty_post_paris_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_gaslimit/block_gaslimit.sol b/examples/test/semanticTests/state_block_gaslimit/block_gaslimit.sol new file mode 100644 index 00000000..0201068b --- /dev/null +++ b/examples/test/semanticTests/state_block_gaslimit/block_gaslimit.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (uint) { + return block.gaslimit; + } +} +// ---- +// f() -> 20000000 +// f() -> 20000000 +// f() -> 20000000 diff --git a/examples/test/semanticTests/state_block_gaslimit/block_gaslimit_standard_input.json b/examples/test/semanticTests/state_block_gaslimit/block_gaslimit_standard_input.json new file mode 100644 index 00000000..da6944e2 --- /dev/null +++ b/examples/test/semanticTests/state_block_gaslimit/block_gaslimit_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_number/block_number.sol b/examples/test/semanticTests/state_block_number/block_number.sol new file mode 100644 index 00000000..01ec3096 --- /dev/null +++ b/examples/test/semanticTests/state_block_number/block_number.sol @@ -0,0 +1,10 @@ +contract C { + constructor() {} + function f() public returns (uint) { + return block.number; + } +} +// ---- +// constructor() +// f() -> 2 +// f() -> 3 diff --git a/examples/test/semanticTests/state_block_number/block_number_standard_input.json b/examples/test/semanticTests/state_block_number/block_number_standard_input.json new file mode 100644 index 00000000..598d8223 --- /dev/null +++ b/examples/test/semanticTests/state_block_number/block_number_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f(uint _index) public returns (bytes32) {\n return blobhash(_index);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "block_prevrandao_pre_paris.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "msg_value.sol": { + "content": "contract C {\n function f() public payable returns (uint) {\n return msg.value;\n }\n}\n// ----\n// f() -> 0\n// f(), 12 ether -> 12000000000000000000\n" + }, + "tx_gasprice.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return tx.gasprice;\n }\n}\n// ----\n// f() -> 3000000000\n// f() -> 3000000000\n// f() -> 3000000000\n" + }, + "block_number.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.number;\n }\n}\n// ----\n// constructor()\n// f() -> 2\n// f() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_prevrandao/block_prevrandao.sol b/examples/test/semanticTests/state_block_prevrandao/block_prevrandao.sol new file mode 100644 index 00000000..590265da --- /dev/null +++ b/examples/test/semanticTests/state_block_prevrandao/block_prevrandao.sol @@ -0,0 +1,9 @@ +contract C { + function f() public view returns (uint) { + return block.prevrandao; + } +} +// ==== +// EVMVersion: >=paris +// ---- +// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777 diff --git a/examples/test/semanticTests/state_block_prevrandao/block_prevrandao_standard_input.json b/examples/test/semanticTests/state_block_prevrandao/block_prevrandao_standard_input.json new file mode 100644 index 00000000..1966dc28 --- /dev/null +++ b/examples/test/semanticTests/state_block_prevrandao/block_prevrandao_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f(uint _index) public returns (bytes32) {\n return blobhash(_index);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris.sol b/examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris.sol new file mode 100644 index 00000000..6824cab5 --- /dev/null +++ b/examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris.sol @@ -0,0 +1,9 @@ +contract C { + function f() public view returns (uint) { + return block.prevrandao; + } +} +// ==== +// EVMVersion: 200000000 diff --git a/examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris_standard_input.json b/examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris_standard_input.json new file mode 100644 index 00000000..27847eab --- /dev/null +++ b/examples/test/semanticTests/state_block_prevrandao_pre_paris/block_prevrandao_pre_paris_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f(uint _index) public returns (bytes32) {\n return blobhash(_index);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "block_prevrandao_pre_paris.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: 200000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_block_timestamp/block_timestamp.sol b/examples/test/semanticTests/state_block_timestamp/block_timestamp.sol new file mode 100644 index 00000000..485ae4be --- /dev/null +++ b/examples/test/semanticTests/state_block_timestamp/block_timestamp.sol @@ -0,0 +1,10 @@ +contract C { + constructor() {} + function f() public returns (uint) { + return block.timestamp; + } +} +// ---- +// constructor() # This is the 1st block # +// f() -> 0x1e # This is the 2nd block (each block is "15 seconds") # +// f() -> 0x2d # This is the 3rd block # diff --git a/examples/test/semanticTests/state_block_timestamp/block_timestamp_standard_input.json b/examples/test/semanticTests/state_block_timestamp/block_timestamp_standard_input.json new file mode 100644 index 00000000..12ad09e7 --- /dev/null +++ b/examples/test/semanticTests/state_block_timestamp/block_timestamp_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_blockhash_basic/blockhash_basic.sol b/examples/test/semanticTests/state_blockhash_basic/blockhash_basic.sol new file mode 100644 index 00000000..64b8d55a --- /dev/null +++ b/examples/test/semanticTests/state_blockhash_basic/blockhash_basic.sol @@ -0,0 +1,27 @@ +contract C { + bytes32 public genesisHash; + bytes32 public currentHash; + constructor() { + require(block.number == 1); + genesisHash = blockhash(0); + currentHash = blockhash(1); + } + function f(uint blockNumber) public returns (bytes32) { + return blockhash(blockNumber); + } +} +// ---- +// constructor() +// gas irOptimized: 80338 +// gas irOptimized code: 27800 +// gas legacy: 83571 +// gas legacy code: 68600 +// gas legacyOptimized: 80338 +// gas legacyOptimized code: 26400 +// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737 +// currentHash() -> 0 +// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737 +// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738 +// f(uint256): 255 -> 0x00 +// f(uint256): 256 -> 0x00 +// f(uint256): 257 -> 0x00 diff --git a/examples/test/semanticTests/state_blockhash_basic/blockhash_basic_standard_input.json b/examples/test/semanticTests/state_blockhash_basic/blockhash_basic_standard_input.json new file mode 100644 index 00000000..bf9ce74c --- /dev/null +++ b/examples/test/semanticTests/state_blockhash_basic/blockhash_basic_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_gasleft/gasleft.sol b/examples/test/semanticTests/state_gasleft/gasleft.sol new file mode 100644 index 00000000..6ce623ce --- /dev/null +++ b/examples/test/semanticTests/state_gasleft/gasleft.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (bool) { + return gasleft() > 0; + } +} +// ---- +// f() -> true +// f() -> true +// f() -> true diff --git a/examples/test/semanticTests/state_gasleft/gasleft_standard_input.json b/examples/test/semanticTests/state_gasleft/gasleft_standard_input.json new file mode 100644 index 00000000..a4da6562 --- /dev/null +++ b/examples/test/semanticTests/state_gasleft/gasleft_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_msg_data/msg_data.sol b/examples/test/semanticTests/state_msg_data/msg_data.sol new file mode 100644 index 00000000..5a240461 --- /dev/null +++ b/examples/test/semanticTests/state_msg_data/msg_data.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (bytes calldata) { + return msg.data; + } + function g(uint,bool) public returns (bytes calldata) { + return msg.data; + } +} +// ---- +// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912 +// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216 diff --git a/examples/test/semanticTests/state_msg_data/msg_data_standard_input.json b/examples/test/semanticTests/state_msg_data/msg_data_standard_input.json new file mode 100644 index 00000000..3d2f9a6a --- /dev/null +++ b/examples/test/semanticTests/state_msg_data/msg_data_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_msg_sender/msg_sender.sol b/examples/test/semanticTests/state_msg_sender/msg_sender.sol new file mode 100644 index 00000000..951d1f52 --- /dev/null +++ b/examples/test/semanticTests/state_msg_sender/msg_sender.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (address) { + return msg.sender; + } +} +// ---- +// f() -> 0x1212121212121212121212121212120000000012 diff --git a/examples/test/semanticTests/state_msg_sender/msg_sender_standard_input.json b/examples/test/semanticTests/state_msg_sender/msg_sender_standard_input.json new file mode 100644 index 00000000..f122d17f --- /dev/null +++ b/examples/test/semanticTests/state_msg_sender/msg_sender_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_msg_sig/msg_sig.sol b/examples/test/semanticTests/state_msg_sig/msg_sig.sol new file mode 100644 index 00000000..f2f26e24 --- /dev/null +++ b/examples/test/semanticTests/state_msg_sig/msg_sig.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (bytes4) { + return msg.sig; + } + function g() public returns (bytes4) { + return msg.sig; + } +} +// ---- +// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000 +// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/state_msg_sig/msg_sig_standard_input.json b/examples/test/semanticTests/state_msg_sig/msg_sig_standard_input.json new file mode 100644 index 00000000..6f8b9f0d --- /dev/null +++ b/examples/test/semanticTests/state_msg_sig/msg_sig_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_msg_value/msg_value.sol b/examples/test/semanticTests/state_msg_value/msg_value.sol new file mode 100644 index 00000000..143183b8 --- /dev/null +++ b/examples/test/semanticTests/state_msg_value/msg_value.sol @@ -0,0 +1,8 @@ +contract C { + function f() public payable returns (uint) { + return msg.value; + } +} +// ---- +// f() -> 0 +// f(), 12 ether -> 12000000000000000000 diff --git a/examples/test/semanticTests/state_msg_value/msg_value_standard_input.json b/examples/test/semanticTests/state_msg_value/msg_value_standard_input.json new file mode 100644 index 00000000..3b28bfaf --- /dev/null +++ b/examples/test/semanticTests/state_msg_value/msg_value_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f(uint _index) public returns (bytes32) {\n return blobhash(_index);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "block_prevrandao_pre_paris.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "msg_value.sol": { + "content": "contract C {\n function f() public payable returns (uint) {\n return msg.value;\n }\n}\n// ----\n// f() -> 0\n// f(), 12 ether -> 12000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_tx_gasprice/tx_gasprice.sol b/examples/test/semanticTests/state_tx_gasprice/tx_gasprice.sol new file mode 100644 index 00000000..0d6dc6ae --- /dev/null +++ b/examples/test/semanticTests/state_tx_gasprice/tx_gasprice.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (uint) { + return tx.gasprice; + } +} +// ---- +// f() -> 3000000000 +// f() -> 3000000000 +// f() -> 3000000000 diff --git a/examples/test/semanticTests/state_tx_gasprice/tx_gasprice_standard_input.json b/examples/test/semanticTests/state_tx_gasprice/tx_gasprice_standard_input.json new file mode 100644 index 00000000..5f175c47 --- /dev/null +++ b/examples/test/semanticTests/state_tx_gasprice/tx_gasprice_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + }, + "gasleft.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return gasleft() > 0;\n }\n}\n// ----\n// f() -> true\n// f() -> true\n// f() -> true\n" + }, + "block_difficulty.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: 200000000\n// f() -> 200000000\n// f() -> 200000000\n" + }, + "block_timestamp.sol": { + "content": "contract C {\n constructor() {}\n function f() public returns (uint) {\n return block.timestamp;\n }\n}\n// ----\n// constructor() # This is the 1st block #\n// f() -> 0x1e # This is the 2nd block (each block is \"15 seconds\") #\n// f() -> 0x2d # This is the 3rd block #\n" + }, + "block_basefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.basefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := basefee()\n }\n }\n}\n// ====\n// EVMVersion: >=london\n// ----\n// f() -> 7\n// g() -> 7\n// f() -> 7\n// g() -> 7\n" + }, + "blobhash.sol": { + "content": "contract C {\n function f(uint _index) public returns (bytes32) {\n return blobhash(_index);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f(uint256): 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n// f(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n// f(uint256): 2 -> 0x00\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_prevrandao.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "block_prevrandao_pre_paris.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.prevrandao;\n }\n}\n// ====\n// EVMVersion: 200000000\n" + }, + "msg_value.sol": { + "content": "contract C {\n function f() public payable returns (uint) {\n return msg.value;\n }\n}\n// ----\n// f() -> 0\n// f(), 12 ether -> 12000000000000000000\n" + }, + "tx_gasprice.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return tx.gasprice;\n }\n}\n// ----\n// f() -> 3000000000\n// f() -> 3000000000\n// f() -> 3000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_tx_origin/tx_origin.sol b/examples/test/semanticTests/state_tx_origin/tx_origin.sol new file mode 100644 index 00000000..aa726c35 --- /dev/null +++ b/examples/test/semanticTests/state_tx_origin/tx_origin.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (address) { + return tx.origin; + } +} +// ---- +// f() -> 0x9292929292929292929292929292929292929292 +// f() -> 0x9292929292929292929292929292929292929292 +// f() -> 0x9292929292929292929292929292929292929292 diff --git a/examples/test/semanticTests/state_tx_origin/tx_origin_standard_input.json b/examples/test/semanticTests/state_tx_origin/tx_origin_standard_input.json new file mode 100644 index 00000000..79f874c5 --- /dev/null +++ b/examples/test/semanticTests/state_tx_origin/tx_origin_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + }, + "block_difficulty_post_paris.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.difficulty;\n }\n}\n// ====\n// EVMVersion: >=paris\n// ----\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777\n" + }, + "msg_data.sol": { + "content": "contract C {\n function f() public returns (bytes calldata) {\n return msg.data;\n }\n function g(uint,bool) public returns (bytes calldata) {\n return msg.data;\n }\n}\n// ----\n// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912\n// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216\n" + }, + "block_gaslimit.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.gaslimit;\n }\n}\n// ----\n// f() -> 20000000\n// f() -> 20000000\n// f() -> 20000000\n" + }, + "msg_sig.sol": { + "content": "contract C {\n function f() public returns (bytes4) {\n return msg.sig;\n }\n function g() public returns (bytes4) {\n return msg.sig;\n }\n}\n// ----\n// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n" + }, + "blockhash_basic.sol": { + "content": "contract C {\n bytes32 public genesisHash;\n bytes32 public currentHash;\n constructor() {\n require(block.number == 1);\n genesisHash = blockhash(0);\n currentHash = blockhash(1);\n }\n function f(uint blockNumber) public returns (bytes32) {\n return blockhash(blockNumber);\n }\n}\n// ----\n// constructor()\n// gas irOptimized: 80338\n// gas irOptimized code: 27800\n// gas legacy: 83571\n// gas legacy code: 68600\n// gas legacyOptimized: 80338\n// gas legacyOptimized code: 26400\n// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// currentHash() -> 0\n// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737\n// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738\n// f(uint256): 255 -> 0x00\n// f(uint256): 256 -> 0x00\n// f(uint256): 257 -> 0x00\n" + }, + "block_blobbasefee.sol": { + "content": "contract C {\n function f() public view returns (uint) {\n return block.blobbasefee;\n }\n function g() public view returns (uint ret) {\n assembly {\n ret := blobbasefee()\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1\n// g() -> 1\n// f() -> 1\n// g() -> 1\n" + }, + "block_coinbase.sol": { + "content": "contract C {\n function f() public returns (address payable) {\n return block.coinbase;\n }\n}\n// ----\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n// f() -> 0x7878787878787878787878787878787878787878\n" + }, + "tx_origin.sol": { + "content": "contract C {\n function f() public returns (address) {\n return tx.origin;\n }\n}\n// ----\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n// f() -> 0x9292929292929292929292929292929292929292\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash.sol b/examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash.sol new file mode 100644 index 00000000..df81a469 --- /dev/null +++ b/examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash.sol @@ -0,0 +1,12 @@ +contract C { + function f() public returns (bytes32) { + // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly: + // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001 + // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002 + return (blobhash)(0); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001 diff --git a/examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash_standard_input.json b/examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash_standard_input.json new file mode 100644 index 00000000..ddb90cc1 --- /dev/null +++ b/examples/test/semanticTests/state_uncalled_blobhash/uncalled_blobhash_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function f() public returns (address) {\n return msg.sender;\n }\n}\n// ----\n// f() -> 0x1212121212121212121212121212120000000012\n" + }, + "uncalled_blobhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // NOTE: The `tx_context.blob_hashes` is injected into EVMHost with the following hashes, indexed accordingly:\n // 0 -> 0x0100000000000000000000000000000000000000000000000000000000000001\n // 1 -> 0x0100000000000000000000000000000000000000000000000000000000000002\n return (blobhash)(0);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0x0100000000000000000000000000000000000000000000000000000000000001\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash.sol b/examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash.sol new file mode 100644 index 00000000..4e2526c7 --- /dev/null +++ b/examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (bytes32) { + return (blockhash)(block.number - 1); + } +} +// ---- +// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738 diff --git a/examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash_standard_input.json b/examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash_standard_input.json new file mode 100644 index 00000000..37e59b83 --- /dev/null +++ b/examples/test/semanticTests/state_uncalled_blockhash/uncalled_blockhash_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "block_chainid.sol": { + "content": "contract C {\n function f() public returns (uint) {\n return block.chainid;\n }\n}\n// ====\n// EVMVersion: >=istanbul\n// ----\n// f() -> 1\n// f() -> 1\n// f() -> 1\n" + }, + "uncalled_blockhash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n return (blockhash)(block.number - 1);\n }\n}\n// ----\n// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_var_initialization_1/state_var_initialization.sol b/examples/test/semanticTests/state_var_initialization_1/state_var_initialization.sol new file mode 100644 index 00000000..a8b0f108 --- /dev/null +++ b/examples/test/semanticTests/state_var_initialization_1/state_var_initialization.sol @@ -0,0 +1,12 @@ +contract C { + uint public i = 1; + uint public k = 2; + + constructor() { + i = i + i; + k = k - i; + } +} +// ---- +// i() -> 2 +// k() -> 0 diff --git a/examples/test/semanticTests/state_var_initialization_1/state_var_initialization_standard_input.json b/examples/test/semanticTests/state_var_initialization_1/state_var_initialization_standard_input.json new file mode 100644 index 00000000..8da3ef1b --- /dev/null +++ b/examples/test/semanticTests/state_var_initialization_1/state_var_initialization_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + }, + "isoltestFormatting.sol": { + "content": "contract C {\n function f() public returns (uint[5] memory) {\n uint[5] memory a = [4, 11, 0x111, uint(3355443), 2222222222222222222];\n return a;\n }\n function g() public returns (uint[5] memory) {\n uint[5] memory a = [16, 256, 257, uint(0x333333), 0x1ed6eb565788e38e];\n return a;\n }\n}\n// ----\n// f() -> 4, 11, 0x0111, 0x333333, 2222222222222222222\n// g() -> 0x10, 0x0100, 0x0101, 0x333333, 2222222222222222222\n" + }, + "constructor_inheritance_init_order_3_viaIR.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: true\n// ----\n// x() -> 2\n" + }, + "constructor_with_params.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 81170\n// gas irOptimized code: 20200\n// gas legacy: 83613\n// gas legacy code: 32000\n// i() -> 2\n// k() -> 0\n" + }, + "byte_array_to_storage_cleanup.sol": { + "content": "contract C {\n event ev(uint[], uint);\n bytes public s;\n function h() external returns (bytes memory) {\n uint[] memory x = new uint[](2);\n emit ev(x, 0x21);\n bytes memory m = new bytes(63);\n s = m;\n s.push();\n return s;\n }\n function g() external returns (bytes memory) {\n bytes memory m = new bytes(63);\n assembly {\n mstore8(add(m, add(32, 63)), 0x42)\n }\n s = m;\n s.push();\n return s;\n }\n function f(bytes calldata c) external returns (bytes memory) {\n s = c;\n s.push();\n return s;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// constructor() ->\n// gas irOptimized: 82100\n// gas irOptimized code: 357600\n// gas legacy: 101532\n// gas legacy code: 604800\n// gas legacyOptimized: 84956\n// gas legacyOptimized code: 391800\n// h() -> 0x20, 0x40, 0x00, 0\n// ~ emit ev(uint256[],uint256): 0x40, 0x21, 0x02, 0x00, 0x00\n// g() -> 0x20, 0x40, 0, 0x00\n// f(bytes): 0x20, 33, 0, -1 -> 0x20, 0x22, 0, 0xff00000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_calldata_dynamic_array.sol": { + "content": "contract C {\n function f(int16[] calldata a) external returns (bool correct) {\n uint32 x = uint32(uint16(a[1]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x7fff;\n }\n}\n// ----\n// f(int16[]): 0x20, 0x02, 0x7fff, 0x7fff -> true\n" + }, + "c99_scoping_activation.sol": { + "content": "contract test {\n function f() pure public returns (uint) {\n uint x = 7;\n {\n x = 3; // This should still assign to the outer variable\n uint x;\n x = 4; // This should assign to the new one\n }\n return x;\n }\n function g() pure public returns (uint x) {\n x = 7;\n {\n x = 3;\n uint x;\n return x; // This returns the new variable, i.e. 0\n }\n }\n function h() pure public returns (uint x, uint a, uint b) {\n x = 7;\n {\n x = 3;\n a = x; // This should read from the outer\n uint x = 4;\n b = x;\n }\n }\n function i() pure public returns (uint x, uint a) {\n x = 7;\n {\n x = 3;\n uint x = x; // This should read from the outer and assign to the inner\n a = x;\n }\n }\n}\n// ----\n// f() -> 3\n// g() -> 0\n// h() -> 3, 3, 4\n// i() -> 3, 3\n" + }, + "empty_contract.sol": { + "content": "contract test {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// i_am_not_there() -> FAILURE\n" + }, + "dirty_calldata_bytes.sol": { + "content": "contract C {\n function f(bytes calldata b) public returns (bool correct) {\n bytes1 a = b[3];\n uint r;\n assembly {\n r := a\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f(bytes): 0x20, 0x04, \"dead\" -> true\n" + }, + "state_var_initialization.sol": { + "content": "contract C {\n uint public i = 1;\n uint public k = 2;\n\n constructor() {\n i = i + i;\n k = k - i;\n }\n}\n// ----\n// i() -> 2\n// k() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order.sol b/examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order.sol new file mode 100644 index 00000000..6f8a59c1 --- /dev/null +++ b/examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order.sol @@ -0,0 +1,12 @@ +contract A { + uint public x = 0; + uint y = f(); + function f() public returns (uint256) { + ++x; + return 42; + } +} +contract B is A { +} +// ---- +// x() -> 1 diff --git a/examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order_standard_input.json b/examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order_standard_input.json new file mode 100644 index 00000000..7f5be994 --- /dev/null +++ b/examples/test/semanticTests/state_variables_init_order_1/state_variables_init_order_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2.sol b/examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2.sol new file mode 100644 index 00000000..9003898e --- /dev/null +++ b/examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2.sol @@ -0,0 +1,16 @@ +contract A { + uint public x = 0; + uint y = f(); + function f() public returns (uint256) { + ++x; + return 42; + } +} +contract B is A { + uint public z; + constructor() { + z = x; + } +} +// ---- +// z() -> 1 diff --git a/examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2_standard_input.json b/examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2_standard_input.json new file mode 100644 index 00000000..b391caf3 --- /dev/null +++ b/examples/test/semanticTests/state_variables_init_order_2_1/state_variables_init_order_2_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3.sol b/examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3.sol new file mode 100644 index 00000000..0a0aad59 --- /dev/null +++ b/examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3.sol @@ -0,0 +1,29 @@ +contract A { + uint public a = 42; + uint public b; + uint public c; + constructor(uint x) { + b = a; + a = x; + } + function f(uint x) public returns (uint256) { c = x * 3; return 23; } +} +contract B is A { + uint public d = f(a); + uint public e = b; + uint public b_a; + uint public b_b; + uint public b_c; + constructor() A(17) { b_a = a; b_b = b; b_c = c; } +} +// ==== +// compileViaYul: true +// ---- +// a() -> 17 +// b() -> 42 +// c() -> 51 +// b_a() -> 17 +// b_b() -> 42 +// b_c() -> 51 +// d() -> 23 +// e() -> 42 diff --git a/examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3_standard_input.json b/examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3_standard_input.json new file mode 100644 index 00000000..99771774 --- /dev/null +++ b/examples/test/semanticTests/state_variables_init_order_3_1/state_variables_init_order_3_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue.sol b/examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue.sol new file mode 100644 index 00000000..76f2bc4a --- /dev/null +++ b/examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue.sol @@ -0,0 +1,14 @@ +contract test { + function f() public pure returns(uint r) { + uint i = 0; + do + { + if (i > 0) return 0; + i++; + continue; + } while (false); + return 42; + } +} +// ---- +// f() -> 42 diff --git a/examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue_standard_input.json b/examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue_standard_input.json new file mode 100644 index 00000000..363dd507 --- /dev/null +++ b/examples/test/semanticTests/statements_do_while_loop_continue/do_while_loop_continue_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "do_while_loop_continue.sol": { + "content": "contract test {\n function f() public pure returns(uint r) {\n uint i = 0;\n do\n {\n if (i > 0) return 0;\n i++;\n continue;\n } while (false);\n return 42;\n }\n}\n// ----\n// f() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array.sol b/examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array.sol new file mode 100644 index 00000000..f309bcf1 --- /dev/null +++ b/examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array.sol @@ -0,0 +1,15 @@ +contract test { + mapping(uint => uint[8]) public data; + mapping(uint => uint[]) public dynamicData; + constructor() { + data[2][2] = 8; + for (uint i = 0; i < 3; i++) + dynamicData[2].push(); + dynamicData[2][2] = 8; + } +} +// ---- +// data(uint256,uint256): 2, 2 -> 8 +// data(uint256,uint256): 2, 8 -> FAILURE # NB: the original code contained a bug here # +// dynamicData(uint256,uint256): 2, 2 -> 8 +// dynamicData(uint256,uint256): 2, 8 -> FAILURE diff --git a/examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array_standard_input.json b/examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array_standard_input.json new file mode 100644 index 00000000..ee423328 --- /dev/null +++ b/examples/test/semanticTests/storage_accessors_mapping_for_array/accessors_mapping_for_array_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + }, + "complex_accessors.sol": { + "content": "contract test {\n mapping(uint256 => bytes4) public to_string_map;\n mapping(uint256 => bool) public to_bool_map;\n mapping(uint256 => uint256) public to_uint_map;\n mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n constructor() {\n to_string_map[42] = \"24\";\n to_bool_map[42] = false;\n to_uint_map[42] = 12;\n to_multiple_map[42][23] = 31;\n }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n" + }, + "packed_storage_structs_uint.sol": { + "content": "contract C {\n struct str {\n uint8 a;\n uint16 b;\n uint248 c;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = 2;\n if (data.a != 2) return 2;\n data.b = 0xabcd;\n if (data.b != 0xabcd) return 3;\n data.c = 0x1234567890;\n if (data.c != 0x1234567890) return 4;\n if (data.a != 2) return 5;\n data.a = 8;\n if (data.a != 8) return 6;\n if (data.b != 0xabcd) return 7;\n data.b = 0xdcab;\n if (data.b != 0xdcab) return 8;\n if (data.c != 0x1234567890) return 9;\n data.c = 0x9876543210;\n if (data.c != 0x9876543210) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "mapping_state.sol": { + "content": "contract Ballot {\n\tmapping(address => bool) canVote;\n\tmapping(address => uint) voteCount;\n\tmapping(address => bool) voted;\n\tfunction getVoteCount(address addr) public returns (uint retVoteCount) {\n\t\treturn voteCount[addr];\n\t}\n\tfunction grantVoteRight(address addr) public {\n\t\tcanVote[addr] = true;\n\t}\n\tfunction vote(address voter, address vote) public returns (bool success) {\n\t\tif (!canVote[voter] || voted[voter]) return false;\n\t\tvoted[voter] = true;\n\t\tvoteCount[vote] = voteCount[vote] + 1;\n\t\treturn true;\n\t}\n}\n// ----\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// vote(address,address): 0, 2 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// grantVoteRight(address): 0 ->\n// grantVoteRight(address): 1 ->\n// vote(address,address): 0, 2 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 0, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 2, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// grantVoteRight(address): 2 ->\n// vote(address,address): 2, 1 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 1\n// getVoteCount(address): 2 -> 1\n" + }, + "accessors_mapping_for_array.sol": { + "content": "contract test {\n mapping(uint => uint[8]) public data;\n mapping(uint => uint[]) public dynamicData;\n constructor() {\n data[2][2] = 8;\n for (uint i = 0; i < 3; i++)\n dynamicData[2].push();\n dynamicData[2][2] = 8;\n }\n}\n// ----\n// data(uint256,uint256): 2, 2 -> 8\n// data(uint256,uint256): 2, 8 -> FAILURE # NB: the original code contained a bug here #\n// dynamicData(uint256,uint256): 2, 2 -> 8\n// dynamicData(uint256,uint256): 2, 8 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_array_accessor/array_accessor.sol b/examples/test/semanticTests/storage_array_accessor/array_accessor.sol new file mode 100644 index 00000000..599931a3 --- /dev/null +++ b/examples/test/semanticTests/storage_array_accessor/array_accessor.sol @@ -0,0 +1,33 @@ +contract test { + uint[8] public data; + uint[] public dynamicData; + uint24[] public smallTypeData; + struct st { uint a; uint[] finalArray; } + mapping(uint256 => mapping(uint256 => st[5])) public multiple_map; + + constructor() { + data[0] = 8; + + dynamicData.push(); + dynamicData.push(); + dynamicData.push(8); + + smallTypeData = new uint24[](128); + smallTypeData[1] = 22; + smallTypeData[127] = 2; + + multiple_map[2][1][2].a = 3; + for (uint i = 0; i < 4; i++) + multiple_map[2][1][2].finalArray.push(); + multiple_map[2][1][2].finalArray[3] = 5; + } +} +// ---- +// data(uint256): 0 -> 8 +// data(uint256): 8 -> FAILURE +// dynamicData(uint256): 2 -> 8 +// dynamicData(uint256): 8 -> FAILURE +// smallTypeData(uint256): 1 -> 22 +// smallTypeData(uint256): 127 -> 2 +// smallTypeData(uint256): 128 -> FAILURE +// multiple_map(uint256,uint256,uint256): 2, 1, 2 -> 3 diff --git a/examples/test/semanticTests/storage_array_accessor/array_accessor_standard_input.json b/examples/test/semanticTests/storage_array_accessor/array_accessor_standard_input.json new file mode 100644 index 00000000..2278d795 --- /dev/null +++ b/examples/test/semanticTests/storage_array_accessor/array_accessor_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + }, + "complex_accessors.sol": { + "content": "contract test {\n mapping(uint256 => bytes4) public to_string_map;\n mapping(uint256 => bool) public to_bool_map;\n mapping(uint256 => uint256) public to_uint_map;\n mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n constructor() {\n to_string_map[42] = \"24\";\n to_bool_map[42] = false;\n to_uint_map[42] = 12;\n to_multiple_map[42][23] = 31;\n }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n" + }, + "packed_storage_structs_uint.sol": { + "content": "contract C {\n struct str {\n uint8 a;\n uint16 b;\n uint248 c;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = 2;\n if (data.a != 2) return 2;\n data.b = 0xabcd;\n if (data.b != 0xabcd) return 3;\n data.c = 0x1234567890;\n if (data.c != 0x1234567890) return 4;\n if (data.a != 2) return 5;\n data.a = 8;\n if (data.a != 8) return 6;\n if (data.b != 0xabcd) return 7;\n data.b = 0xdcab;\n if (data.b != 0xdcab) return 8;\n if (data.c != 0x1234567890) return 9;\n data.c = 0x9876543210;\n if (data.c != 0x9876543210) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "mapping_state.sol": { + "content": "contract Ballot {\n\tmapping(address => bool) canVote;\n\tmapping(address => uint) voteCount;\n\tmapping(address => bool) voted;\n\tfunction getVoteCount(address addr) public returns (uint retVoteCount) {\n\t\treturn voteCount[addr];\n\t}\n\tfunction grantVoteRight(address addr) public {\n\t\tcanVote[addr] = true;\n\t}\n\tfunction vote(address voter, address vote) public returns (bool success) {\n\t\tif (!canVote[voter] || voted[voter]) return false;\n\t\tvoted[voter] = true;\n\t\tvoteCount[vote] = voteCount[vote] + 1;\n\t\treturn true;\n\t}\n}\n// ----\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// vote(address,address): 0, 2 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// grantVoteRight(address): 0 ->\n// grantVoteRight(address): 1 ->\n// vote(address,address): 0, 2 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 0, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 2, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// grantVoteRight(address): 2 ->\n// vote(address,address): 2, 1 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 1\n// getVoteCount(address): 2 -> 1\n" + }, + "accessors_mapping_for_array.sol": { + "content": "contract test {\n mapping(uint => uint[8]) public data;\n mapping(uint => uint[]) public dynamicData;\n constructor() {\n data[2][2] = 8;\n for (uint i = 0; i < 3; i++)\n dynamicData[2].push();\n dynamicData[2][2] = 8;\n }\n}\n// ----\n// data(uint256,uint256): 2, 2 -> 8\n// data(uint256,uint256): 2, 8 -> FAILURE # NB: the original code contained a bug here #\n// dynamicData(uint256,uint256): 2, 2 -> 8\n// dynamicData(uint256,uint256): 2, 8 -> FAILURE\n" + }, + "packed_functions.sol": { + "content": "contract C {\n // these should take the same slot\n function() internal returns (uint) a;\n function() external returns (uint) b;\n function() external returns (uint) c;\n function() internal returns (uint) d;\n uint8 public x;\n\n function set() public {\n x = 2;\n d = g;\n c = this.h;\n b = this.h;\n a = g;\n }\n\n function t1() public returns (uint256) {\n return a();\n }\n\n function t2() public returns (uint256) {\n return b();\n }\n\n function t3() public returns (uint256) {\n return a();\n }\n\n function t4() public returns (uint256) {\n return b();\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n function h() public returns (uint256) {\n return 8;\n }\n}\n// ----\n// set() ->\n// t1() -> 7\n// t2() -> 8\n// t3() -> 7\n// t4() -> 8\n// x() -> 2\n" + }, + "array_accessor.sol": { + "content": "contract test {\n uint[8] public data;\n uint[] public dynamicData;\n uint24[] public smallTypeData;\n struct st { uint a; uint[] finalArray; }\n mapping(uint256 => mapping(uint256 => st[5])) public multiple_map;\n\n constructor() {\n data[0] = 8;\n\n dynamicData.push();\n dynamicData.push();\n dynamicData.push(8);\n\n smallTypeData = new uint24[](128);\n smallTypeData[1] = 22;\n smallTypeData[127] = 2;\n\n multiple_map[2][1][2].a = 3;\n for (uint i = 0; i < 4; i++)\n multiple_map[2][1][2].finalArray.push();\n multiple_map[2][1][2].finalArray[3] = 5;\n }\n}\n// ----\n// data(uint256): 0 -> 8\n// data(uint256): 8 -> FAILURE\n// dynamicData(uint256): 2 -> 8\n// dynamicData(uint256): 8 -> FAILURE\n// smallTypeData(uint256): 1 -> 22\n// smallTypeData(uint256): 127 -> 2\n// smallTypeData(uint256): 128 -> FAILURE\n// multiple_map(uint256,uint256,uint256): 2, 1, 2 -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits.sol b/examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits.sol new file mode 100644 index 00000000..51cba026 --- /dev/null +++ b/examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits.sol @@ -0,0 +1,29 @@ +contract Test { + int16[] public x = [-1, -2]; + int16[2] public y = [-5, -6]; + int16 z; + function f() public returns (int16[] memory) { + int8[] memory t = new int8[](2); + t[0] = -3; + t[1] = -4; + x = t; + return x; + } + function g() public returns (int16[2] memory) { + int8[2] memory t = [-3, -4]; + y = t; + return y; + } + function h(int8 t) public returns (int16) { + z = t; + return z; + } +} +// ---- +// x(uint256): 0 -> -1 +// x(uint256): 1 -> -2 +// y(uint256): 0 -> -5 +// y(uint256): 1 -> -6 +// f() -> 0x20, 2, -3, -4 +// g() -> -3, -4 +// h(int8): -10 -> -10 diff --git a/examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits_standard_input.json b/examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits_standard_input.json new file mode 100644 index 00000000..89859200 --- /dev/null +++ b/examples/test/semanticTests/storage_chop_sign_bits/chop_sign_bits_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_complex_accessors/complex_accessors.sol b/examples/test/semanticTests/storage_complex_accessors/complex_accessors.sol new file mode 100644 index 00000000..59ad86a1 --- /dev/null +++ b/examples/test/semanticTests/storage_complex_accessors/complex_accessors.sol @@ -0,0 +1,17 @@ +contract test { + mapping(uint256 => bytes4) public to_string_map; + mapping(uint256 => bool) public to_bool_map; + mapping(uint256 => uint256) public to_uint_map; + mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map; + constructor() { + to_string_map[42] = "24"; + to_bool_map[42] = false; + to_uint_map[42] = 12; + to_multiple_map[42][23] = 31; + } +} +// ---- +// to_string_map(uint256): 42 -> "24" +// to_bool_map(uint256): 42 -> false +// to_uint_map(uint256): 42 -> 12 +// to_multiple_map(uint256,uint256): 42, 23 -> 31 diff --git a/examples/test/semanticTests/storage_complex_accessors/complex_accessors_standard_input.json b/examples/test/semanticTests/storage_complex_accessors/complex_accessors_standard_input.json new file mode 100644 index 00000000..5a1ace54 --- /dev/null +++ b/examples/test/semanticTests/storage_complex_accessors/complex_accessors_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + }, + "complex_accessors.sol": { + "content": "contract test {\n mapping(uint256 => bytes4) public to_string_map;\n mapping(uint256 => bool) public to_bool_map;\n mapping(uint256 => uint256) public to_uint_map;\n mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n constructor() {\n to_string_map[42] = \"24\";\n to_bool_map[42] = false;\n to_uint_map[42] = 12;\n to_multiple_map[42][23] = 31;\n }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty.sol b/examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty.sol new file mode 100644 index 00000000..8a795373 --- /dev/null +++ b/examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty.sol @@ -0,0 +1,32 @@ +contract Test { + bytes x; + function set(bytes memory _a) public { x = _a; } +} +// ---- +// set(bytes): 0x20, 3, "abc" +// storageEmpty -> 0 +// set(bytes): 0x20, 0 +// storageEmpty -> 1 +// set(bytes): 0x20, 31, "1234567890123456789012345678901" +// storageEmpty -> 0 +// set(bytes): 0x20, 36, "12345678901234567890123456789012", "XXXX" +// storageEmpty -> 0 +// set(bytes): 0x20, 3, "abc" +// storageEmpty -> 0 +// set(bytes): 0x20, 0 +// storageEmpty -> 1 +// set(bytes): 0x20, 3, "abc" +// storageEmpty -> 0 +// set(bytes): 0x20, 36, "12345678901234567890123456789012", "XXXX" +// storageEmpty -> 0 +// set(bytes): 0x20, 0 +// storageEmpty -> 1 +// set(bytes): 0x20, 66, "12345678901234567890123456789012", "12345678901234567890123456789012", "12" +// gas irOptimized: 111849 +// gas legacy: 112734 +// gas legacyOptimized: 112084 +// storageEmpty -> 0 +// set(bytes): 0x20, 3, "abc" +// storageEmpty -> 0 +// set(bytes): 0x20, 0 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty_standard_input.json b/examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty_standard_input.json new file mode 100644 index 00000000..8d3c465b --- /dev/null +++ b/examples/test/semanticTests/storage_empty_nonempty_empty/empty_nonempty_empty_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_mapping_state/mapping_state.sol b/examples/test/semanticTests/storage_mapping_state/mapping_state.sol new file mode 100644 index 00000000..9059e72d --- /dev/null +++ b/examples/test/semanticTests/storage_mapping_state/mapping_state.sol @@ -0,0 +1,44 @@ +contract Ballot { + mapping(address => bool) canVote; + mapping(address => uint) voteCount; + mapping(address => bool) voted; + function getVoteCount(address addr) public returns (uint retVoteCount) { + return voteCount[addr]; + } + function grantVoteRight(address addr) public { + canVote[addr] = true; + } + function vote(address voter, address vote) public returns (bool success) { + if (!canVote[voter] || voted[voter]) return false; + voted[voter] = true; + voteCount[vote] = voteCount[vote] + 1; + return true; + } +} +// ---- +// getVoteCount(address): 0 -> 0 +// getVoteCount(address): 1 -> 0 +// getVoteCount(address): 2 -> 0 +// vote(address,address): 0, 2 -> false +// getVoteCount(address): 0 -> 0 +// getVoteCount(address): 1 -> 0 +// getVoteCount(address): 2 -> 0 +// grantVoteRight(address): 0 -> +// grantVoteRight(address): 1 -> +// vote(address,address): 0, 2 -> true +// getVoteCount(address): 0 -> 0 +// getVoteCount(address): 1 -> 0 +// getVoteCount(address): 2 -> 1 +// vote(address,address): 0, 1 -> false +// getVoteCount(address): 0 -> 0 +// getVoteCount(address): 1 -> 0 +// getVoteCount(address): 2 -> 1 +// vote(address,address): 2, 1 -> false +// getVoteCount(address): 0 -> 0 +// getVoteCount(address): 1 -> 0 +// getVoteCount(address): 2 -> 1 +// grantVoteRight(address): 2 -> +// vote(address,address): 2, 1 -> true +// getVoteCount(address): 0 -> 0 +// getVoteCount(address): 1 -> 1 +// getVoteCount(address): 2 -> 1 diff --git a/examples/test/semanticTests/storage_mapping_state/mapping_state_standard_input.json b/examples/test/semanticTests/storage_mapping_state/mapping_state_standard_input.json new file mode 100644 index 00000000..11bef0a9 --- /dev/null +++ b/examples/test/semanticTests/storage_mapping_state/mapping_state_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + }, + "complex_accessors.sol": { + "content": "contract test {\n mapping(uint256 => bytes4) public to_string_map;\n mapping(uint256 => bool) public to_bool_map;\n mapping(uint256 => uint256) public to_uint_map;\n mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n constructor() {\n to_string_map[42] = \"24\";\n to_bool_map[42] = false;\n to_uint_map[42] = 12;\n to_multiple_map[42][23] = 31;\n }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n" + }, + "packed_storage_structs_uint.sol": { + "content": "contract C {\n struct str {\n uint8 a;\n uint16 b;\n uint248 c;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = 2;\n if (data.a != 2) return 2;\n data.b = 0xabcd;\n if (data.b != 0xabcd) return 3;\n data.c = 0x1234567890;\n if (data.c != 0x1234567890) return 4;\n if (data.a != 2) return 5;\n data.a = 8;\n if (data.a != 8) return 6;\n if (data.b != 0xabcd) return 7;\n data.b = 0xdcab;\n if (data.b != 0xdcab) return 8;\n if (data.c != 0x1234567890) return 9;\n data.c = 0x9876543210;\n if (data.c != 0x9876543210) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "mapping_state.sol": { + "content": "contract Ballot {\n\tmapping(address => bool) canVote;\n\tmapping(address => uint) voteCount;\n\tmapping(address => bool) voted;\n\tfunction getVoteCount(address addr) public returns (uint retVoteCount) {\n\t\treturn voteCount[addr];\n\t}\n\tfunction grantVoteRight(address addr) public {\n\t\tcanVote[addr] = true;\n\t}\n\tfunction vote(address voter, address vote) public returns (bool success) {\n\t\tif (!canVote[voter] || voted[voter]) return false;\n\t\tvoted[voter] = true;\n\t\tvoteCount[vote] = voteCount[vote] + 1;\n\t\treturn true;\n\t}\n}\n// ----\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// vote(address,address): 0, 2 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// grantVoteRight(address): 0 ->\n// grantVoteRight(address): 1 ->\n// vote(address,address): 0, 2 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 0, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 2, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// grantVoteRight(address): 2 ->\n// vote(address,address): 2, 1 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 1\n// getVoteCount(address): 2 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_mapping_string_key/mapping_string_key.sol b/examples/test/semanticTests/storage_mapping_string_key/mapping_string_key.sol new file mode 100644 index 00000000..be751692 --- /dev/null +++ b/examples/test/semanticTests/storage_mapping_string_key/mapping_string_key.sol @@ -0,0 +1,22 @@ +contract C { + mapping (string => uint) m_nameToRecord; + function set(string calldata key, uint value) external { + m_nameToRecord[key] = value; + } + function get(string calldata key) external view returns (uint) { + return m_nameToRecord[key]; + } + function setFixed(uint value) external { + m_nameToRecord["fixed"] = value; + } + function getFixed() external view returns (uint) { + return m_nameToRecord["fixed"]; + } +} +// ---- +// set(string,uint256): 0x40, 8, 3, "abc" -> +// get(string): 0x20, 3, "abc" -> 8 +// get(string): 0x20, 3, "abe" -> 0 +// getFixed() -> 0 +// setFixed(uint256): 9 -> +// getFixed() -> 9 diff --git a/examples/test/semanticTests/storage_mapping_string_key/mapping_string_key_standard_input.json b/examples/test/semanticTests/storage_mapping_string_key/mapping_string_key_standard_input.json new file mode 100644 index 00000000..20c1edcf --- /dev/null +++ b/examples/test/semanticTests/storage_mapping_string_key/mapping_string_key_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete.sol b/examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete.sol new file mode 100644 index 00000000..f4407bb6 --- /dev/null +++ b/examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete.sol @@ -0,0 +1,39 @@ +contract C { + mapping (uint => uint)[][] a; + + function n1(uint key, uint value) public { + a.push(); + mapping (uint => uint)[] storage b = a[a.length - 1]; + b.push(); + b[b.length - 1][key] = value; + } + + function n2() public { + a.push(); + mapping (uint => uint)[] storage b = a[a.length - 1]; + b.push(); + } + + function map(uint key) public view returns (uint) { + mapping (uint => uint)[] storage b = a[a.length - 1]; + return b[b.length - 1][key]; + } + + function p() public { + a.pop(); + } + + function d() public returns (uint) { + delete a; + return a.length; + } +} +// ---- +// n1(uint256,uint256): 42, 64 -> +// map(uint256): 42 -> 64 +// p() -> +// n2() -> +// map(uint256): 42 -> 64 +// d() -> 0 +// n2() -> +// map(uint256): 42 -> 64 diff --git a/examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete_standard_input.json b/examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete_standard_input.json new file mode 100644 index 00000000..bf1c09ac --- /dev/null +++ b/examples/test/semanticTests/storage_mappings_array2d_pop_delete/mappings_array2d_pop_delete_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete.sol b/examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete.sol new file mode 100644 index 00000000..97390057 --- /dev/null +++ b/examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete.sol @@ -0,0 +1,34 @@ +contract C { + mapping (uint => uint)[] a; + + function n1(uint key, uint value) public { + a.push(); + a[a.length - 1][key] = value; + } + + function n2() public { + a.push(); + } + + function map(uint key) public view returns (uint) { + return a[a.length - 1][key]; + } + + function p() public { + a.pop(); + } + + function d() public returns (uint) { + delete a; + return a.length; + } +} +// ---- +// n1(uint256,uint256): 42, 64 -> +// map(uint256): 42 -> 64 +// p() -> +// n2() -> +// map(uint256): 42 -> 64 +// d() -> 0 +// n2() -> +// map(uint256): 42 -> 64 diff --git a/examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete_standard_input.json b/examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete_standard_input.json new file mode 100644 index 00000000..3c4fb176 --- /dev/null +++ b/examples/test/semanticTests/storage_mappings_array_pop_delete/mappings_array_pop_delete_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_packed_functions/packed_functions.sol b/examples/test/semanticTests/storage_packed_functions/packed_functions.sol new file mode 100644 index 00000000..564a3fab --- /dev/null +++ b/examples/test/semanticTests/storage_packed_functions/packed_functions.sol @@ -0,0 +1,47 @@ +contract C { + // these should take the same slot + function() internal returns (uint) a; + function() external returns (uint) b; + function() external returns (uint) c; + function() internal returns (uint) d; + uint8 public x; + + function set() public { + x = 2; + d = g; + c = this.h; + b = this.h; + a = g; + } + + function t1() public returns (uint256) { + return a(); + } + + function t2() public returns (uint256) { + return b(); + } + + function t3() public returns (uint256) { + return a(); + } + + function t4() public returns (uint256) { + return b(); + } + + function g() public returns (uint256) { + return 7; + } + + function h() public returns (uint256) { + return 8; + } +} +// ---- +// set() -> +// t1() -> 7 +// t2() -> 8 +// t3() -> 7 +// t4() -> 8 +// x() -> 2 diff --git a/examples/test/semanticTests/storage_packed_functions/packed_functions_standard_input.json b/examples/test/semanticTests/storage_packed_functions/packed_functions_standard_input.json new file mode 100644 index 00000000..727eb6dc --- /dev/null +++ b/examples/test/semanticTests/storage_packed_functions/packed_functions_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + }, + "complex_accessors.sol": { + "content": "contract test {\n mapping(uint256 => bytes4) public to_string_map;\n mapping(uint256 => bool) public to_bool_map;\n mapping(uint256 => uint256) public to_uint_map;\n mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n constructor() {\n to_string_map[42] = \"24\";\n to_bool_map[42] = false;\n to_uint_map[42] = 12;\n to_multiple_map[42][23] = 31;\n }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n" + }, + "packed_storage_structs_uint.sol": { + "content": "contract C {\n struct str {\n uint8 a;\n uint16 b;\n uint248 c;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = 2;\n if (data.a != 2) return 2;\n data.b = 0xabcd;\n if (data.b != 0xabcd) return 3;\n data.c = 0x1234567890;\n if (data.c != 0x1234567890) return 4;\n if (data.a != 2) return 5;\n data.a = 8;\n if (data.a != 8) return 6;\n if (data.b != 0xabcd) return 7;\n data.b = 0xdcab;\n if (data.b != 0xdcab) return 8;\n if (data.c != 0x1234567890) return 9;\n data.c = 0x9876543210;\n if (data.c != 0x9876543210) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "mapping_state.sol": { + "content": "contract Ballot {\n\tmapping(address => bool) canVote;\n\tmapping(address => uint) voteCount;\n\tmapping(address => bool) voted;\n\tfunction getVoteCount(address addr) public returns (uint retVoteCount) {\n\t\treturn voteCount[addr];\n\t}\n\tfunction grantVoteRight(address addr) public {\n\t\tcanVote[addr] = true;\n\t}\n\tfunction vote(address voter, address vote) public returns (bool success) {\n\t\tif (!canVote[voter] || voted[voter]) return false;\n\t\tvoted[voter] = true;\n\t\tvoteCount[vote] = voteCount[vote] + 1;\n\t\treturn true;\n\t}\n}\n// ----\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// vote(address,address): 0, 2 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 0\n// grantVoteRight(address): 0 ->\n// grantVoteRight(address): 1 ->\n// vote(address,address): 0, 2 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 0, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// vote(address,address): 2, 1 -> false\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 0\n// getVoteCount(address): 2 -> 1\n// grantVoteRight(address): 2 ->\n// vote(address,address): 2, 1 -> true\n// getVoteCount(address): 0 -> 0\n// getVoteCount(address): 1 -> 1\n// getVoteCount(address): 2 -> 1\n" + }, + "accessors_mapping_for_array.sol": { + "content": "contract test {\n mapping(uint => uint[8]) public data;\n mapping(uint => uint[]) public dynamicData;\n constructor() {\n data[2][2] = 8;\n for (uint i = 0; i < 3; i++)\n dynamicData[2].push();\n dynamicData[2][2] = 8;\n }\n}\n// ----\n// data(uint256,uint256): 2, 2 -> 8\n// data(uint256,uint256): 2, 8 -> FAILURE # NB: the original code contained a bug here #\n// dynamicData(uint256,uint256): 2, 2 -> 8\n// dynamicData(uint256,uint256): 2, 8 -> FAILURE\n" + }, + "packed_functions.sol": { + "content": "contract C {\n // these should take the same slot\n function() internal returns (uint) a;\n function() external returns (uint) b;\n function() external returns (uint) c;\n function() internal returns (uint) d;\n uint8 public x;\n\n function set() public {\n x = 2;\n d = g;\n c = this.h;\n b = this.h;\n a = g;\n }\n\n function t1() public returns (uint256) {\n return a();\n }\n\n function t2() public returns (uint256) {\n return b();\n }\n\n function t3() public returns (uint256) {\n return a();\n }\n\n function t4() public returns (uint256) {\n return b();\n }\n\n function g() public returns (uint256) {\n return 7;\n }\n\n function h() public returns (uint256) {\n return 8;\n }\n}\n// ----\n// set() ->\n// t1() -> 7\n// t2() -> 8\n// t3() -> 7\n// t4() -> 8\n// x() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow.sol b/examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow.sol new file mode 100644 index 00000000..af2ecc70 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow.sol @@ -0,0 +1,15 @@ +contract C { + uint16 x = 0x1234; + uint16 a = 0xffff; + uint16 b; + + function f() public returns (uint256, uint256, uint256, uint256) { + unchecked { a++; } + uint256 c = b; + delete b; + unchecked { a -= 2; } + return (x, c, b, a); + } +} +// ---- +// f() -> 0x1234, 0x0, 0x0, 0xfffe diff --git a/examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow_standard_input.json b/examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow_standard_input.json new file mode 100644 index 00000000..794ab410 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_overflow/packed_storage_overflow_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed.sol b/examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed.sol new file mode 100644 index 00000000..92cb82c9 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed.sol @@ -0,0 +1,23 @@ +contract C { + int8 a; + uint8 b; + int8 c; + uint8 d; + + function test() + public + returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4) + { + a = -2; + unchecked { + b = (0 - uint8(a)) * 2; + c = a * int8(120) * int8(121); + } + x1 = uint256(int256(a)); + x2 = b; + x3 = uint256(int256(c)); + x4 = d; + } +} +// ---- +// test() -> -2, 4, -112, 0 diff --git a/examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed_standard_input.json b/examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed_standard_input.json new file mode 100644 index 00000000..592fb2ae --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_signed/packed_storage_signed_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes.sol b/examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes.sol new file mode 100644 index 00000000..7d19bc47 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes.sol @@ -0,0 +1,47 @@ +contract C { + struct s1 { + bytes1 a; + bytes1 b; + bytes10 c; + bytes9 d; + bytes10 e; + } + struct s2 { + bytes1 a; + s1 inner; + bytes1 b; + bytes1 c; + } + bytes1 x; + s2 data; + bytes1 y; + + function test() public returns (bool) { + x = 0x01; + data.a = 0x02; + data.inner.a = 0x03; + data.inner.b = 0x04; + data.inner.c = "1234567890"; + data.inner.d = "123456789"; + data.inner.e = "abcdefghij"; + data.b = 0x05; + data.c = bytes1(0x06); + y = 0x07; + return + x == 0x01 && + data.a == 0x02 && + data.inner.a == 0x03 && + data.inner.b == 0x04 && + data.inner.c == "1234567890" && + data.inner.d == "123456789" && + data.inner.e == "abcdefghij" && + data.b == 0x05 && + data.c == bytes1(0x06) && + y == 0x07; + } +} +// ---- +// test() -> true +// gas irOptimized: 132633 +// gas legacy: 136010 +// gas legacyOptimized: 133478 diff --git a/examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes_standard_input.json b/examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes_standard_input.json new file mode 100644 index 00000000..e09a9c88 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_structs_bytes/packed_storage_structs_bytes_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum.sol b/examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum.sol new file mode 100644 index 00000000..cda71d33 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum.sol @@ -0,0 +1,32 @@ +contract C { + enum small {A, B, C, D} + enum larger {A, B, C, D, E} + struct str { + small a; + small b; + larger c; + larger d; + } + str data; + + function test() public returns (uint256) { + data.a = small.B; + if (data.a != small.B) return 2; + data.b = small.C; + if (data.b != small.C) return 3; + data.c = larger.D; + if (data.c != larger.D) return 4; + if (data.a != small.B) return 5; + data.a = small.C; + if (data.a != small.C) return 6; + if (data.b != small.C) return 7; + data.b = small.D; + if (data.b != small.D) return 8; + if (data.c != larger.D) return 9; + data.c = larger.B; + if (data.c != larger.B) return 10; + return 1; + } +} +// ---- +// test() -> 1 diff --git a/examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum_standard_input.json b/examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum_standard_input.json new file mode 100644 index 00000000..1bf147ea --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_structs_enum/packed_storage_structs_enum_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint.sol b/examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint.sol new file mode 100644 index 00000000..ea3c03d6 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint.sol @@ -0,0 +1,29 @@ +contract C { + struct str { + uint8 a; + uint16 b; + uint248 c; + } + str data; + + function test() public returns (uint256) { + data.a = 2; + if (data.a != 2) return 2; + data.b = 0xabcd; + if (data.b != 0xabcd) return 3; + data.c = 0x1234567890; + if (data.c != 0x1234567890) return 4; + if (data.a != 2) return 5; + data.a = 8; + if (data.a != 8) return 6; + if (data.b != 0xabcd) return 7; + data.b = 0xdcab; + if (data.b != 0xdcab) return 8; + if (data.c != 0x1234567890) return 9; + data.c = 0x9876543210; + if (data.c != 0x9876543210) return 10; + return 1; + } +} +// ---- +// test() -> 1 diff --git a/examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint_standard_input.json b/examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint_standard_input.json new file mode 100644 index 00000000..e23f4640 --- /dev/null +++ b/examples/test/semanticTests/storage_packed_storage_structs_uint/packed_storage_structs_uint_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + }, + "complex_accessors.sol": { + "content": "contract test {\n mapping(uint256 => bytes4) public to_string_map;\n mapping(uint256 => bool) public to_bool_map;\n mapping(uint256 => uint256) public to_uint_map;\n mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n constructor() {\n to_string_map[42] = \"24\";\n to_bool_map[42] = false;\n to_uint_map[42] = 12;\n to_multiple_map[42][23] = 31;\n }\n}\n// ----\n// to_string_map(uint256): 42 -> \"24\"\n// to_bool_map(uint256): 42 -> false\n// to_uint_map(uint256): 42 -> 12\n// to_multiple_map(uint256,uint256): 42, 23 -> 31\n" + }, + "packed_storage_structs_uint.sol": { + "content": "contract C {\n struct str {\n uint8 a;\n uint16 b;\n uint248 c;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = 2;\n if (data.a != 2) return 2;\n data.b = 0xabcd;\n if (data.b != 0xabcd) return 3;\n data.c = 0x1234567890;\n if (data.c != 0x1234567890) return 4;\n if (data.a != 2) return 5;\n data.a = 8;\n if (data.a != 8) return 6;\n if (data.b != 0xabcd) return 7;\n data.b = 0xdcab;\n if (data.b != 0xdcab) return 8;\n if (data.c != 0x1234567890) return 9;\n data.c = 0x9876543210;\n if (data.c != 0x9876543210) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_simple_accessor/simple_accessor.sol b/examples/test/semanticTests/storage_simple_accessor/simple_accessor.sol new file mode 100644 index 00000000..7aaeb4db --- /dev/null +++ b/examples/test/semanticTests/storage_simple_accessor/simple_accessor.sol @@ -0,0 +1,8 @@ +contract test { + uint256 public data; + constructor() { + data = 8; + } +} +// ---- +// data() -> 8 diff --git a/examples/test/semanticTests/storage_simple_accessor/simple_accessor_standard_input.json b/examples/test/semanticTests/storage_simple_accessor/simple_accessor_standard_input.json new file mode 100644 index 00000000..ec6f12c5 --- /dev/null +++ b/examples/test/semanticTests/storage_simple_accessor/simple_accessor_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_state_smoke_test/state_smoke_test.sol b/examples/test/semanticTests/storage_state_smoke_test/state_smoke_test.sol new file mode 100644 index 00000000..1b464531 --- /dev/null +++ b/examples/test/semanticTests/storage_state_smoke_test/state_smoke_test.sol @@ -0,0 +1,21 @@ +contract test { + uint256 value1; + uint256 value2; + function get(uint8 which) public returns (uint256 value) { + if (which == 0) return value1; + else return value2; + } + function set(uint8 which, uint256 value) public { + if (which == 0) value1 = value; + else value2 = value; + } +} +// ---- +// get(uint8): 0x00 -> 0 +// get(uint8): 0x01 -> 0 +// set(uint8,uint256): 0x00, 0x1234 -> +// set(uint8,uint256): 0x01, 0x8765 -> +// get(uint8): 0x00 -> 0x1234 +// get(uint8): 0x01 -> 0x8765 +// set(uint8,uint256): 0x00, 0x03 -> +// get(uint8): 0x00 -> 0x03 diff --git a/examples/test/semanticTests/storage_state_smoke_test/state_smoke_test_standard_input.json b/examples/test/semanticTests/storage_state_smoke_test/state_smoke_test_standard_input.json new file mode 100644 index 00000000..9c04a13a --- /dev/null +++ b/examples/test/semanticTests/storage_state_smoke_test/state_smoke_test_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + }, + "empty_nonempty_empty.sol": { + "content": "contract Test {\n bytes x;\n function set(bytes memory _a) public { x = _a; }\n}\n// ----\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 31, \"1234567890123456789012345678901\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 36, \"12345678901234567890123456789012\", \"XXXX\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n// set(bytes): 0x20, 66, \"12345678901234567890123456789012\", \"12345678901234567890123456789012\", \"12\"\n// gas irOptimized: 111849\n// gas legacy: 112734\n// gas legacyOptimized: 112084\n// storageEmpty -> 0\n// set(bytes): 0x20, 3, \"abc\"\n// storageEmpty -> 0\n// set(bytes): 0x20, 0\n// storageEmpty -> 1\n" + }, + "mappings_array2d_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[][] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t\tb[b.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\tb.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\tmapping (uint => uint)[] storage b = a[a.length - 1];\n\t\treturn b[b.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "simple_accessor.sol": { + "content": "contract test {\n uint256 public data;\n constructor() {\n data = 8;\n }\n}\n// ----\n// data() -> 8\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n mapping (string => uint) m_nameToRecord;\n function set(string calldata key, uint value) external {\n m_nameToRecord[key] = value;\n }\n function get(string calldata key) external view returns (uint) {\n return m_nameToRecord[key];\n }\n function setFixed(uint value) external {\n m_nameToRecord[\"fixed\"] = value;\n }\n function getFixed() external view returns (uint) {\n return m_nameToRecord[\"fixed\"];\n }\n}\n// ----\n// set(string,uint256): 0x40, 8, 3, \"abc\" ->\n// get(string): 0x20, 3, \"abc\" -> 8\n// get(string): 0x20, 3, \"abe\" -> 0\n// getFixed() -> 0\n// setFixed(uint256): 9 ->\n// getFixed() -> 9\n" + }, + "packed_storage_overflow.sol": { + "content": "contract C {\n uint16 x = 0x1234;\n uint16 a = 0xffff;\n uint16 b;\n\n function f() public returns (uint256, uint256, uint256, uint256) {\n unchecked { a++; }\n uint256 c = b;\n delete b;\n unchecked { a -= 2; }\n return (x, c, b, a);\n }\n}\n// ----\n// f() -> 0x1234, 0x0, 0x0, 0xfffe\n" + }, + "packed_storage_signed.sol": { + "content": "contract C {\n int8 a;\n uint8 b;\n int8 c;\n uint8 d;\n\n function test()\n public\n returns (uint256 x1, uint256 x2, uint256 x3, uint256 x4)\n {\n a = -2;\n unchecked {\n b = (0 - uint8(a)) * 2;\n c = a * int8(120) * int8(121);\n }\n x1 = uint256(int256(a));\n x2 = b;\n x3 = uint256(int256(c));\n x4 = d;\n }\n}\n// ----\n// test() -> -2, 4, -112, 0\n" + }, + "packed_storage_structs_bytes.sol": { + "content": "contract C {\n struct s1 {\n bytes1 a;\n bytes1 b;\n bytes10 c;\n bytes9 d;\n bytes10 e;\n }\n struct s2 {\n bytes1 a;\n s1 inner;\n bytes1 b;\n bytes1 c;\n }\n bytes1 x;\n s2 data;\n bytes1 y;\n\n function test() public returns (bool) {\n x = 0x01;\n data.a = 0x02;\n data.inner.a = 0x03;\n data.inner.b = 0x04;\n data.inner.c = \"1234567890\";\n data.inner.d = \"123456789\";\n data.inner.e = \"abcdefghij\";\n data.b = 0x05;\n data.c = bytes1(0x06);\n y = 0x07;\n return\n x == 0x01 &&\n data.a == 0x02 &&\n data.inner.a == 0x03 &&\n data.inner.b == 0x04 &&\n data.inner.c == \"1234567890\" &&\n data.inner.d == \"123456789\" &&\n data.inner.e == \"abcdefghij\" &&\n data.b == 0x05 &&\n data.c == bytes1(0x06) &&\n y == 0x07;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 132633\n// gas legacy: 136010\n// gas legacyOptimized: 133478\n" + }, + "chop_sign_bits.sol": { + "content": "contract Test {\n int16[] public x = [-1, -2];\n int16[2] public y = [-5, -6];\n int16 z;\n function f() public returns (int16[] memory) {\n int8[] memory t = new int8[](2);\n t[0] = -3;\n t[1] = -4;\n x = t;\n return x;\n }\n function g() public returns (int16[2] memory) {\n int8[2] memory t = [-3, -4];\n y = t;\n return y;\n }\n function h(int8 t) public returns (int16) {\n z = t;\n return z;\n }\n}\n// ----\n// x(uint256): 0 -> -1\n// x(uint256): 1 -> -2\n// y(uint256): 0 -> -5\n// y(uint256): 1 -> -6\n// f() -> 0x20, 2, -3, -4\n// g() -> -3, -4\n// h(int8): -10 -> -10\n" + }, + "mappings_array_pop_delete.sol": { + "content": "contract C {\n\tmapping (uint => uint)[] a;\n\n\tfunction n1(uint key, uint value) public {\n\t\ta.push();\n\t\ta[a.length - 1][key] = value;\n\t}\n\n\tfunction n2() public {\n\t\ta.push();\n\t}\n\n\tfunction map(uint key) public view returns (uint) {\n\t\treturn a[a.length - 1][key];\n\t}\n\n\tfunction p() public {\n\t\ta.pop();\n\t}\n\n\tfunction d() public returns (uint) {\n\t\tdelete a;\n\t\treturn a.length;\n\t}\n}\n// ----\n// n1(uint256,uint256): 42, 64 ->\n// map(uint256): 42 -> 64\n// p() ->\n// n2() ->\n// map(uint256): 42 -> 64\n// d() -> 0\n// n2() ->\n// map(uint256): 42 -> 64\n" + }, + "packed_storage_structs_enum.sol": { + "content": "contract C {\n enum small {A, B, C, D}\n enum larger {A, B, C, D, E}\n struct str {\n small a;\n small b;\n larger c;\n larger d;\n }\n str data;\n\n function test() public returns (uint256) {\n data.a = small.B;\n if (data.a != small.B) return 2;\n data.b = small.C;\n if (data.b != small.C) return 3;\n data.c = larger.D;\n if (data.c != larger.D) return 4;\n if (data.a != small.B) return 5;\n data.a = small.C;\n if (data.a != small.C) return 6;\n if (data.b != small.C) return 7;\n data.b = small.D;\n if (data.b != small.D) return 8;\n if (data.c != larger.D) return 9;\n data.c = larger.B;\n if (data.c != larger.B) return 10;\n return 1;\n }\n}\n// ----\n// test() -> 1\n" + }, + "state_smoke_test.sol": { + "content": "contract test {\n uint256 value1;\n uint256 value2;\n function get(uint8 which) public returns (uint256 value) {\n if (which == 0) return value1;\n else return value2;\n }\n function set(uint8 which, uint256 value) public {\n if (which == 0) value1 = value;\n else value2 = value;\n }\n}\n// ----\n// get(uint8): 0x00 -> 0\n// get(uint8): 0x01 -> 0\n// set(uint8,uint256): 0x00, 0x1234 ->\n// set(uint8,uint256): 0x01, 0x8765 ->\n// get(uint8): 0x00 -> 0x1234\n// get(uint8): 0x01 -> 0x8765\n// set(uint8,uint256): 0x00, 0x03 ->\n// get(uint8): 0x00 -> 0x03\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/storage_struct_accessor/struct_accessor.sol b/examples/test/semanticTests/storage_struct_accessor/struct_accessor.sol new file mode 100644 index 00000000..8d8fc178 --- /dev/null +++ b/examples/test/semanticTests/storage_struct_accessor/struct_accessor.sol @@ -0,0 +1,12 @@ +contract test { + struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; } + mapping(uint => Data) public data; + constructor() { + data[7].a = 1; + data[7].b = 2; + data[7].c[0] = 3; + data[7].d = true; + } +} +// ---- +// data(uint256): 7 -> 1, 2, true diff --git a/examples/test/semanticTests/storage_struct_accessor/struct_accessor_standard_input.json b/examples/test/semanticTests/storage_struct_accessor/struct_accessor_standard_input.json new file mode 100644 index 00000000..e17e6780 --- /dev/null +++ b/examples/test/semanticTests/storage_struct_accessor/struct_accessor_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "struct_accessor.sol": { + "content": "contract test {\n struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }\n mapping(uint => Data) public data;\n constructor() {\n data[7].a = 1;\n data[7].b = 2;\n data[7].c[0] = 3;\n data[7].d = true;\n }\n}\n// ----\n// data(uint256): 7 -> 1, 2, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args.sol b/examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args.sol new file mode 100644 index 00000000..304ccecb --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args.sol @@ -0,0 +1,12 @@ +contract C { + function f(string memory a, string memory b) public returns (string memory) { + return string.concat(a, b); + } +} +// ---- +// f(string,string): 0x40, 0x80, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200 +// f(string,string): 0x40, 0xa0, 64, "abcdabcdabcdabcdabcdabcdabcdabcd", "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 0x20, 0x45, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200 +// f(string,string): 0x40, 0x80, 3, "abc", 3, "def" -> 0x20, 6, "abcdef" +// f(string,string): 0x40, 0xa0, 34, "abcdabcdabcdabcdabcdabcdabcdabcd", "ab", 30, "cdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 0x40, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364 +// f(string,string): 0x40, 0xa0, 34, "abcdabcdabcdabcdabcdabcdabcdabcd", "ab", 34, "cdabcdabcdabcdabcdabcdabcdabcdab", "cd" -> 0x20, 0x44, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44048183293808120317390542201052832727062033572611867748297851798484192067584 +// f(string,string): 0x40, 0x80, 3, "abc", 30, "dabcdabcdabcdabcdabcdabcdabcda" -> 0x20, 0x21, 0x6162636461626364616263646162636461626364616263646162636461626364, 43874346312576839672212443538448152585028080127215369968075725190498334277632 diff --git a/examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args_standard_input.json b/examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args_standard_input.json new file mode 100644 index 00000000..3dc17892 --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_2_args/string_concat_2_args_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "string_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n string memory b = \"\";\n return string.concat(\n string.concat(b),\n string.concat(b, b),\n string.concat(\"\", b),\n string.concat(b, \"\")\n );\n }\n\n function g() public returns (string memory) {\n return string.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (string memory) {\n string memory b = \"\";\n return string.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + }, + "string_concat_nested.sol": { + "content": "contract C {\n function f(string memory a, string memory b, string memory c) public returns (string memory) {\n return string.concat(string.concat(a, b), c);\n }\n}\n// ----\n// f(string,string,string): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "string_concat_2_args.sol": { + "content": "contract C {\n function f(string memory a, string memory b) public returns (string memory) {\n return string.concat(a, b);\n }\n}\n// ----\n// f(string,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x45, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x40, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\" -> 0x20, 0x44, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44048183293808120317390542201052832727062033572611867748297851798484192067584\n// f(string,string): 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\" -> 0x20, 0x21, 0x6162636461626364616263646162636461626364616263646162636461626364, 43874346312576839672212443538448152585028080127215369968075725190498334277632\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types.sol b/examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types.sol new file mode 100644 index 00000000..0891e30c --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types.sol @@ -0,0 +1,35 @@ +contract C{ + string s = "bcdef"; + + function f(string memory a) public returns (string memory) { + return string.concat(a, "bcdef"); + } + function g(string calldata a) public returns (string memory) { + return string.concat(a, "abcdefghabcdefghabcdefghabcdefghab"); + } + function h(string calldata a) public returns (string memory) { + return string.concat(a, s); + } + function j(string calldata a) public returns (string memory) { + string storage ref = s; + return string.concat(a, ref, s); + } + function k(string calldata a, bytes memory b) public returns (string memory) { + return string.concat(a, string(b)); + } + function slice(string calldata a) public returns (string memory) { + require(bytes(a).length > 2, ""); + return string.concat(a[:2], a[2:]); + } + function strParam(bytes calldata a) public returns (string memory) { + return string.concat(string(a), "bcdef"); + } +} +// ---- +// f(string): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200 +// g(string): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 0x42, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636465666768616263646566676861626364656667686162636465666768, 44047497324925121336511606693520958599579173549109180625971642598225011015680 +// h(string): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200 +// j(string): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 0x2a, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928944786876717917111204727192787026596791669343131645116682757734400 +// k(string,bytes): 0x40, 0x80, 32, "abcdabcdabcdabcdabcdabcdabcdabcd", 5, "bcdef" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200 +// slice(string): 0x20, 4, "abcd" -> 0x20, 4, "abcd" +// strParam(bytes): 0x20, 32, "abcdabcdabcdabcdabcdabcdabcdabcd" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200 diff --git a/examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types_standard_input.json b/examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types_standard_input.json new file mode 100644 index 00000000..25fb03cb --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_different_types/string_concat_different_types_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "string_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n string memory b = \"\";\n return string.concat(\n string.concat(b),\n string.concat(b, b),\n string.concat(\"\", b),\n string.concat(b, \"\")\n );\n }\n\n function g() public returns (string memory) {\n return string.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (string memory) {\n string memory b = \"\";\n return string.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + }, + "string_concat_nested.sol": { + "content": "contract C {\n function f(string memory a, string memory b, string memory c) public returns (string memory) {\n return string.concat(string.concat(a, b), c);\n }\n}\n// ----\n// f(string,string,string): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "string_concat_2_args.sol": { + "content": "contract C {\n function f(string memory a, string memory b) public returns (string memory) {\n return string.concat(a, b);\n }\n}\n// ----\n// f(string,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x45, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x40, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\" -> 0x20, 0x44, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44048183293808120317390542201052832727062033572611867748297851798484192067584\n// f(string,string): 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\" -> 0x20, 0x21, 0x6162636461626364616263646162636461626364616263646162636461626364, 43874346312576839672212443538448152585028080127215369968075725190498334277632\n" + }, + "string_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n return string.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "string_concat_different_types.sol": { + "content": "contract C{\n string s = \"bcdef\";\n\n function f(string memory a) public returns (string memory) {\n return string.concat(a, \"bcdef\");\n }\n function g(string calldata a) public returns (string memory) {\n return string.concat(a, \"abcdefghabcdefghabcdefghabcdefghab\");\n }\n function h(string calldata a) public returns (string memory) {\n return string.concat(a, s);\n }\n function j(string calldata a) public returns (string memory) {\n string storage ref = s;\n return string.concat(a, ref, s);\n }\n function k(string calldata a, bytes memory b) public returns (string memory) {\n return string.concat(a, string(b));\n }\n function slice(string calldata a) public returns (string memory) {\n require(bytes(a).length > 2, \"\");\n return string.concat(a[:2], a[2:]);\n }\n function strParam(bytes calldata a) public returns (string memory) {\n return string.concat(string(a), \"bcdef\");\n }\n}\n// ----\n// f(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// g(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x42, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636465666768616263646566676861626364656667686162636465666768, 44047497324925121336511606693520958599579173549109180625971642598225011015680\n// h(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// j(string): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x2a, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928944786876717917111204727192787026596791669343131645116682757734400\n// k(string,bytes): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// slice(string): 0x20, 4, \"abcd\" -> 0x20, 4, \"abcd\"\n// strParam(bytes): 0x20, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list.sol b/examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list.sol new file mode 100644 index 00000000..0297bd26 --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list.sol @@ -0,0 +1,7 @@ +contract C { + function f() public returns (string memory) { + return string.concat(); + } +} +// ---- +// f() -> 0x20, 0 diff --git a/examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list_standard_input.json b/examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list_standard_input.json new file mode 100644 index 00000000..68a293b7 --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_empty_argument_list/string_concat_empty_argument_list_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "string_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n string memory b = \"\";\n return string.concat(\n string.concat(b),\n string.concat(b, b),\n string.concat(\"\", b),\n string.concat(b, \"\")\n );\n }\n\n function g() public returns (string memory) {\n return string.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (string memory) {\n string memory b = \"\";\n return string.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + }, + "string_concat_nested.sol": { + "content": "contract C {\n function f(string memory a, string memory b, string memory c) public returns (string memory) {\n return string.concat(string.concat(a, b), c);\n }\n}\n// ----\n// f(string,string,string): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + }, + "string_concat_2_args.sol": { + "content": "contract C {\n function f(string memory a, string memory b) public returns (string memory) {\n return string.concat(a, b);\n }\n}\n// ----\n// f(string,string): 0x40, 0x80, 32, \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x25, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0xa0, 64, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"abcdabcdabcdabcdabcdabcdabcdabcd\", 5, \"bcdef\" -> 0x20, 0x45, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44502269928904312298000709931354278973409164155382318144318241583783949107200\n// f(string,string): 0x40, 0x80, 3, \"abc\", 3, \"def\" -> 0x20, 6, \"abcdef\"\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 30, \"cdabcdabcdabcdabcdabcdabcdabcd\" -> 0x20, 0x40, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364\n// f(string,string): 0x40, 0xa0, 34, \"abcdabcdabcdabcdabcdabcdabcdabcd\", \"ab\", 34, \"cdabcdabcdabcdabcdabcdabcdabcdab\", \"cd\" -> 0x20, 0x44, 0x6162636461626364616263646162636461626364616263646162636461626364, 0x6162636461626364616263646162636461626364616263646162636461626364, 44048183293808120317390542201052832727062033572611867748297851798484192067584\n// f(string,string): 0x40, 0x80, 3, \"abc\", 30, \"dabcdabcdabcdabcdabcdabcdabcda\" -> 0x20, 0x21, 0x6162636461626364616263646162636461626364616263646162636461626364, 43874346312576839672212443538448152585028080127215369968075725190498334277632\n" + }, + "string_concat_empty_argument_list.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n return string.concat();\n }\n}\n// ----\n// f() -> 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings.sol b/examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings.sol new file mode 100644 index 00000000..b90235b3 --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings.sol @@ -0,0 +1,24 @@ +contract C { + function f() public returns (string memory) { + string memory b = ""; + return string.concat( + string.concat(b), + string.concat(b, b), + string.concat("", b), + string.concat(b, "") + ); + } + + function g() public returns (string memory) { + return string.concat("", "abc", hex"", "abc", unicode""); + } + + function h() public returns (string memory) { + string memory b = ""; + return string.concat(b, "abc", b, "abc", b); + } +} +// ---- +// f() -> 0x20, 0 +// g() -> 0x20, 6, "abcabc" +// h() -> 0x20, 6, "abcabc" diff --git a/examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings_standard_input.json b/examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings_standard_input.json new file mode 100644 index 00000000..db11bd85 --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_empty_strings/string_concat_empty_strings_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "string_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n string memory b = \"\";\n return string.concat(\n string.concat(b),\n string.concat(b, b),\n string.concat(\"\", b),\n string.concat(b, \"\")\n );\n }\n\n function g() public returns (string memory) {\n return string.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (string memory) {\n string memory b = \"\";\n return string.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested.sol b/examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested.sol new file mode 100644 index 00000000..ce594b6a --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested.sol @@ -0,0 +1,7 @@ +contract C { + function f(string memory a, string memory b, string memory c) public returns (string memory) { + return string.concat(string.concat(a, b), c); + } +} +// ---- +// f(string,string,string): 0x60, 0x60, 0x60, 2, "ab" -> 0x20, 6, "ababab" diff --git a/examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested_standard_input.json b/examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested_standard_input.json new file mode 100644 index 00000000..0ef02044 --- /dev/null +++ b/examples/test/semanticTests/strings_concat_string_concat_nested/string_concat_nested_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "string_concat_empty_strings.sol": { + "content": "contract C {\n function f() public returns (string memory) {\n string memory b = \"\";\n return string.concat(\n string.concat(b),\n string.concat(b, b),\n string.concat(\"\", b),\n string.concat(b, \"\")\n );\n }\n\n function g() public returns (string memory) {\n return string.concat(\"\", \"abc\", hex\"\", \"abc\", unicode\"\");\n }\n\n function h() public returns (string memory) {\n string memory b = \"\";\n return string.concat(b, \"abc\", b, \"abc\", b);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g() -> 0x20, 6, \"abcabc\"\n// h() -> 0x20, 6, \"abcabc\"\n" + }, + "string_concat_nested.sol": { + "content": "contract C {\n function f(string memory a, string memory b, string memory c) public returns (string memory) {\n return string.concat(string.concat(a, b), c);\n }\n}\n// ----\n// f(string,string,string): 0x60, 0x60, 0x60, 2, \"ab\" -> 0x20, 6, \"ababab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_constant_string_literal/constant_string_literal.sol b/examples/test/semanticTests/strings_constant_string_literal/constant_string_literal.sol new file mode 100644 index 00000000..817a9081 --- /dev/null +++ b/examples/test/semanticTests/strings_constant_string_literal/constant_string_literal.sol @@ -0,0 +1,23 @@ +contract Test { + bytes32 constant public b = "abcdefghijklmnopq"; + string constant public x = "abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca"; + + constructor() { + string memory xx = x; + bytes32 bb = b; + } + function getB() public returns (bytes32) { return b; } + function getX() public returns (string memory) { return x; } + function getX2() public returns (string memory r) { r = x; } + function unused() public returns (uint) { + "unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused"; + return 2; + } +} +// ---- +// b() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000 +// x() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096 +// getB() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000 +// getX() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096 +// getX2() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096 +// unused() -> 2 diff --git a/examples/test/semanticTests/strings_constant_string_literal/constant_string_literal_standard_input.json b/examples/test/semanticTests/strings_constant_string_literal/constant_string_literal_standard_input.json new file mode 100644 index 00000000..af60ba45 --- /dev/null +++ b/examples/test/semanticTests/strings_constant_string_literal/constant_string_literal_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + }, + "unicode_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d, and \ud83d\ude08\";\n }\n function g() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d,\\\n and \ud83d\ude08\";\n }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n" + }, + "empty_string_input.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n function g(string calldata msg) public pure returns (string memory) {\n return msg;\n }\n function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {\n return (msg, v);\n }\n // Adjusting order of input/output intentionally.\n function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {\n return (msg1, msg2, v);\n }\n function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {\n return (msg1, \"\", v);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g(string): 0x20, 0, \"\" -> 0x20, 0\n// g(string): 0x20, 0 -> 0x20, 0\n// h(string,uint256): 0x40, 0x888, 0, \"\" -> 0x40, 0x0888, 0\n// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0\n" + }, + "empty_storage_string.sol": { + "content": "contract C {\n\n string uninitializedString;\n string emptyString = \"\";\n string nonEmptyString = \"This is a non empty string\";\n string nonEmptyString2 = \"Another string\";\n bytes uninitializedBytes;\n bytes emptyBytes = \"\";\n error EmptyError(string);\n event EmptyEvent(string);\n\n function f() public returns (string memory) {\n return uninitializedString;\n }\n\n function g() public returns (string memory, string memory) {\n return (uninitializedString, emptyString);\n }\n\n function h() public returns (string memory, string memory) {\n return (uninitializedString, nonEmptyString);\n }\n\n function i() public returns (string memory, string memory) {\n return (nonEmptyString, emptyString);\n }\n\n function j(string calldata _s) public returns (string memory) {\n return _s;\n }\n\n function k() public returns (string memory) {\n nonEmptyString2 = \"\";\n return nonEmptyString2;\n }\n\n function l(string calldata _s) public returns (bytes memory) {\n return abi.encode(_s);\n }\n\n function m() public returns (string memory) {\n bytes memory b = abi.encode(emptyString);\n return string(b);\n }\n\n function n() public {\n revert EmptyError(uninitializedString);\n }\n\n function o() public {\n emit EmptyEvent(emptyString);\n }\n\n function p() public {\n emit EmptyEvent(\"\");\n }\n\n function q() public returns (bytes memory) {\n return uninitializedBytes;\n }\n\n function r() public returns (bytes memory) {\n emptyBytes = abi.encode(\"\");\n return emptyBytes;\n }\n\n function s() public returns (bytes memory) {\n emptyBytes = abi.encode(uninitializedString);\n return emptyBytes;\n }\n\n function set(string calldata _s) public {\n nonEmptyString = _s;\n }\n\n function get() public returns (string memory) {\n return nonEmptyString;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() -> 0x20, 0\n// g() -> 0x40, 0x60, 0, 0\n// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328\n// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0\n// j(string): 0x20, 0, \"\" -> 0x20, 0\n// k() -> 0x20, 0\n// l(string): 0x20, 0, \"\" -> 0x20, 0x40, 0x20, 0\n// m() -> 0x20, 0x40, 0x20, 0\n// n() -> FAILURE, hex\"d3f13430\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000000\"\n// o() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// p() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// q() -> 0x20, 0\n// r() -> 0x20, 0x40, 0x20, 0\n// s() -> 0x20, 0x40, 0x20, 0\n// set(string): 0x20, 0, \"\" ->\n// get() -> 0x20, 0\n" + }, + "return_string.sol": { + "content": "contract Main {\n string public s;\n function set(string calldata _s) external {\n s = _s;\n }\n function get1() public returns (string memory r) {\n return s;\n }\n function get2() public returns (string memory r) {\n r = s;\n }\n}\n// ----\n// set(string): 0x20, 5, \"Julia\" ->\n// get1() -> 0x20, 5, \"Julia\"\n// get2() -> 0x20, 5, \"Julia\"\n// s() -> 0x20, 5, \"Julia\"\n" + }, + "empty_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n}\n// ----\n// f() -> 0x20, 0\n" + }, + "constant_string_literal.sol": { + "content": "contract Test {\n bytes32 constant public b = \"abcdefghijklmnopq\";\n string constant public x = \"abefghijklmnopqabcdefghijklmnopqabcdefghijklmnopqabca\";\n\n constructor() {\n string memory xx = x;\n bytes32 bb = b;\n }\n function getB() public returns (bytes32) { return b; }\n function getX() public returns (string memory) { return x; }\n function getX2() public returns (string memory r) { r = x; }\n function unused() public returns (uint) {\n \"unusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunusedunused\";\n return 2;\n }\n}\n// ----\n// b() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000\n// x() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096\n// getB() -> 0x6162636465666768696a6b6c6d6e6f7071000000000000000000000000000000\n// getX() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096\n// getX2() -> 0x20, 0x35, 0x616265666768696a6b6c6d6e6f70716162636465666768696a6b6c6d6e6f7071, 44048183304486788312148433451363384677562177293131179093971701692629931524096\n// unused() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_empty_storage_string/empty_storage_string.sol b/examples/test/semanticTests/strings_empty_storage_string/empty_storage_string.sol new file mode 100644 index 00000000..70d85f24 --- /dev/null +++ b/examples/test/semanticTests/strings_empty_storage_string/empty_storage_string.sol @@ -0,0 +1,100 @@ +contract C { + + string uninitializedString; + string emptyString = ""; + string nonEmptyString = "This is a non empty string"; + string nonEmptyString2 = "Another string"; + bytes uninitializedBytes; + bytes emptyBytes = ""; + error EmptyError(string); + event EmptyEvent(string); + + function f() public returns (string memory) { + return uninitializedString; + } + + function g() public returns (string memory, string memory) { + return (uninitializedString, emptyString); + } + + function h() public returns (string memory, string memory) { + return (uninitializedString, nonEmptyString); + } + + function i() public returns (string memory, string memory) { + return (nonEmptyString, emptyString); + } + + function j(string calldata _s) public returns (string memory) { + return _s; + } + + function k() public returns (string memory) { + nonEmptyString2 = ""; + return nonEmptyString2; + } + + function l(string calldata _s) public returns (bytes memory) { + return abi.encode(_s); + } + + function m() public returns (string memory) { + bytes memory b = abi.encode(emptyString); + return string(b); + } + + function n() public { + revert EmptyError(uninitializedString); + } + + function o() public { + emit EmptyEvent(emptyString); + } + + function p() public { + emit EmptyEvent(""); + } + + function q() public returns (bytes memory) { + return uninitializedBytes; + } + + function r() public returns (bytes memory) { + emptyBytes = abi.encode(""); + return emptyBytes; + } + + function s() public returns (bytes memory) { + emptyBytes = abi.encode(uninitializedString); + return emptyBytes; + } + + function set(string calldata _s) public { + nonEmptyString = _s; + } + + function get() public returns (string memory) { + return nonEmptyString; + } +} +// ==== +// compileViaYul: also +// ---- +// f() -> 0x20, 0 +// g() -> 0x40, 0x60, 0, 0 +// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328 +// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0 +// j(string): 0x20, 0, "" -> 0x20, 0 +// k() -> 0x20, 0 +// l(string): 0x20, 0, "" -> 0x20, 0x40, 0x20, 0 +// m() -> 0x20, 0x40, 0x20, 0 +// n() -> FAILURE, hex"d3f13430", hex"0000000000000000000000000000000000000000000000000000000000000020", hex"0000000000000000000000000000000000000000000000000000000000000000" +// o() -> +// ~ emit EmptyEvent(string): 0x20, 0x00 +// p() -> +// ~ emit EmptyEvent(string): 0x20, 0x00 +// q() -> 0x20, 0 +// r() -> 0x20, 0x40, 0x20, 0 +// s() -> 0x20, 0x40, 0x20, 0 +// set(string): 0x20, 0, "" -> +// get() -> 0x20, 0 diff --git a/examples/test/semanticTests/strings_empty_storage_string/empty_storage_string_standard_input.json b/examples/test/semanticTests/strings_empty_storage_string/empty_storage_string_standard_input.json new file mode 100644 index 00000000..8a0fae17 --- /dev/null +++ b/examples/test/semanticTests/strings_empty_storage_string/empty_storage_string_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + }, + "unicode_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d, and \ud83d\ude08\";\n }\n function g() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d,\\\n and \ud83d\ude08\";\n }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n" + }, + "empty_string_input.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n function g(string calldata msg) public pure returns (string memory) {\n return msg;\n }\n function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {\n return (msg, v);\n }\n // Adjusting order of input/output intentionally.\n function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {\n return (msg1, msg2, v);\n }\n function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {\n return (msg1, \"\", v);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g(string): 0x20, 0, \"\" -> 0x20, 0\n// g(string): 0x20, 0 -> 0x20, 0\n// h(string,uint256): 0x40, 0x888, 0, \"\" -> 0x40, 0x0888, 0\n// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0\n" + }, + "empty_storage_string.sol": { + "content": "contract C {\n\n string uninitializedString;\n string emptyString = \"\";\n string nonEmptyString = \"This is a non empty string\";\n string nonEmptyString2 = \"Another string\";\n bytes uninitializedBytes;\n bytes emptyBytes = \"\";\n error EmptyError(string);\n event EmptyEvent(string);\n\n function f() public returns (string memory) {\n return uninitializedString;\n }\n\n function g() public returns (string memory, string memory) {\n return (uninitializedString, emptyString);\n }\n\n function h() public returns (string memory, string memory) {\n return (uninitializedString, nonEmptyString);\n }\n\n function i() public returns (string memory, string memory) {\n return (nonEmptyString, emptyString);\n }\n\n function j(string calldata _s) public returns (string memory) {\n return _s;\n }\n\n function k() public returns (string memory) {\n nonEmptyString2 = \"\";\n return nonEmptyString2;\n }\n\n function l(string calldata _s) public returns (bytes memory) {\n return abi.encode(_s);\n }\n\n function m() public returns (string memory) {\n bytes memory b = abi.encode(emptyString);\n return string(b);\n }\n\n function n() public {\n revert EmptyError(uninitializedString);\n }\n\n function o() public {\n emit EmptyEvent(emptyString);\n }\n\n function p() public {\n emit EmptyEvent(\"\");\n }\n\n function q() public returns (bytes memory) {\n return uninitializedBytes;\n }\n\n function r() public returns (bytes memory) {\n emptyBytes = abi.encode(\"\");\n return emptyBytes;\n }\n\n function s() public returns (bytes memory) {\n emptyBytes = abi.encode(uninitializedString);\n return emptyBytes;\n }\n\n function set(string calldata _s) public {\n nonEmptyString = _s;\n }\n\n function get() public returns (string memory) {\n return nonEmptyString;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() -> 0x20, 0\n// g() -> 0x40, 0x60, 0, 0\n// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328\n// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0\n// j(string): 0x20, 0, \"\" -> 0x20, 0\n// k() -> 0x20, 0\n// l(string): 0x20, 0, \"\" -> 0x20, 0x40, 0x20, 0\n// m() -> 0x20, 0x40, 0x20, 0\n// n() -> FAILURE, hex\"d3f13430\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000000\"\n// o() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// p() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// q() -> 0x20, 0\n// r() -> 0x20, 0x40, 0x20, 0\n// s() -> 0x20, 0x40, 0x20, 0\n// set(string): 0x20, 0, \"\" ->\n// get() -> 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_empty_string/empty_string.sol b/examples/test/semanticTests/strings_empty_string/empty_string.sol new file mode 100644 index 00000000..f023c723 --- /dev/null +++ b/examples/test/semanticTests/strings_empty_string/empty_string.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure returns (string memory) { + return ""; + } +} +// ---- +// f() -> 0x20, 0 diff --git a/examples/test/semanticTests/strings_empty_string/empty_string_standard_input.json b/examples/test/semanticTests/strings_empty_string/empty_string_standard_input.json new file mode 100644 index 00000000..7f5f37d4 --- /dev/null +++ b/examples/test/semanticTests/strings_empty_string/empty_string_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + }, + "unicode_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d, and \ud83d\ude08\";\n }\n function g() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d,\\\n and \ud83d\ude08\";\n }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n" + }, + "empty_string_input.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n function g(string calldata msg) public pure returns (string memory) {\n return msg;\n }\n function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {\n return (msg, v);\n }\n // Adjusting order of input/output intentionally.\n function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {\n return (msg1, msg2, v);\n }\n function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {\n return (msg1, \"\", v);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g(string): 0x20, 0, \"\" -> 0x20, 0\n// g(string): 0x20, 0 -> 0x20, 0\n// h(string,uint256): 0x40, 0x888, 0, \"\" -> 0x40, 0x0888, 0\n// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0\n" + }, + "empty_storage_string.sol": { + "content": "contract C {\n\n string uninitializedString;\n string emptyString = \"\";\n string nonEmptyString = \"This is a non empty string\";\n string nonEmptyString2 = \"Another string\";\n bytes uninitializedBytes;\n bytes emptyBytes = \"\";\n error EmptyError(string);\n event EmptyEvent(string);\n\n function f() public returns (string memory) {\n return uninitializedString;\n }\n\n function g() public returns (string memory, string memory) {\n return (uninitializedString, emptyString);\n }\n\n function h() public returns (string memory, string memory) {\n return (uninitializedString, nonEmptyString);\n }\n\n function i() public returns (string memory, string memory) {\n return (nonEmptyString, emptyString);\n }\n\n function j(string calldata _s) public returns (string memory) {\n return _s;\n }\n\n function k() public returns (string memory) {\n nonEmptyString2 = \"\";\n return nonEmptyString2;\n }\n\n function l(string calldata _s) public returns (bytes memory) {\n return abi.encode(_s);\n }\n\n function m() public returns (string memory) {\n bytes memory b = abi.encode(emptyString);\n return string(b);\n }\n\n function n() public {\n revert EmptyError(uninitializedString);\n }\n\n function o() public {\n emit EmptyEvent(emptyString);\n }\n\n function p() public {\n emit EmptyEvent(\"\");\n }\n\n function q() public returns (bytes memory) {\n return uninitializedBytes;\n }\n\n function r() public returns (bytes memory) {\n emptyBytes = abi.encode(\"\");\n return emptyBytes;\n }\n\n function s() public returns (bytes memory) {\n emptyBytes = abi.encode(uninitializedString);\n return emptyBytes;\n }\n\n function set(string calldata _s) public {\n nonEmptyString = _s;\n }\n\n function get() public returns (string memory) {\n return nonEmptyString;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() -> 0x20, 0\n// g() -> 0x40, 0x60, 0, 0\n// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328\n// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0\n// j(string): 0x20, 0, \"\" -> 0x20, 0\n// k() -> 0x20, 0\n// l(string): 0x20, 0, \"\" -> 0x20, 0x40, 0x20, 0\n// m() -> 0x20, 0x40, 0x20, 0\n// n() -> FAILURE, hex\"d3f13430\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000000\"\n// o() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// p() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// q() -> 0x20, 0\n// r() -> 0x20, 0x40, 0x20, 0\n// s() -> 0x20, 0x40, 0x20, 0\n// set(string): 0x20, 0, \"\" ->\n// get() -> 0x20, 0\n" + }, + "return_string.sol": { + "content": "contract Main {\n string public s;\n function set(string calldata _s) external {\n s = _s;\n }\n function get1() public returns (string memory r) {\n return s;\n }\n function get2() public returns (string memory r) {\n r = s;\n }\n}\n// ----\n// set(string): 0x20, 5, \"Julia\" ->\n// get1() -> 0x20, 5, \"Julia\"\n// get2() -> 0x20, 5, \"Julia\"\n// s() -> 0x20, 5, \"Julia\"\n" + }, + "empty_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n}\n// ----\n// f() -> 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_empty_string_input/empty_string_input.sol b/examples/test/semanticTests/strings_empty_string_input/empty_string_input.sol new file mode 100644 index 00000000..bd9fbc85 --- /dev/null +++ b/examples/test/semanticTests/strings_empty_string_input/empty_string_input.sol @@ -0,0 +1,28 @@ +contract C { + function f() public pure returns (string memory) { + return ""; + } + function g(string calldata msg) public pure returns (string memory) { + return msg; + } + function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) { + return (msg, v); + } + // Adjusting order of input/output intentionally. + function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) { + return (msg1, msg2, v); + } + function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) { + return (msg1, "", v); + } +} +// ---- +// f() -> 0x20, 0 +// g(string): 0x20, 0, "" -> 0x20, 0 +// g(string): 0x20, 0 -> 0x20, 0 +// h(string,uint256): 0x40, 0x888, 0, "" -> 0x40, 0x0888, 0 +// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0 +// i(string,uint256,string): 0x60, 0x888, 0x60, 0, "" -> 0x60, 0x80, 0x0888, 0, 0 +// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0 +// j(string,uint256): 0x40, 0x888, 0, "" -> 0x60, 0x80, 0x0888, 0, 0 +// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0 diff --git a/examples/test/semanticTests/strings_empty_string_input/empty_string_input_standard_input.json b/examples/test/semanticTests/strings_empty_string_input/empty_string_input_standard_input.json new file mode 100644 index 00000000..f1a2f9a6 --- /dev/null +++ b/examples/test/semanticTests/strings_empty_string_input/empty_string_input_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + }, + "unicode_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d, and \ud83d\ude08\";\n }\n function g() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d,\\\n and \ud83d\ude08\";\n }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n" + }, + "empty_string_input.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n function g(string calldata msg) public pure returns (string memory) {\n return msg;\n }\n function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {\n return (msg, v);\n }\n // Adjusting order of input/output intentionally.\n function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {\n return (msg1, msg2, v);\n }\n function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {\n return (msg1, \"\", v);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g(string): 0x20, 0, \"\" -> 0x20, 0\n// g(string): 0x20, 0 -> 0x20, 0\n// h(string,uint256): 0x40, 0x888, 0, \"\" -> 0x40, 0x0888, 0\n// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_return_string/return_string.sol b/examples/test/semanticTests/strings_return_string/return_string.sol new file mode 100644 index 00000000..704a7859 --- /dev/null +++ b/examples/test/semanticTests/strings_return_string/return_string.sol @@ -0,0 +1,17 @@ +contract Main { + string public s; + function set(string calldata _s) external { + s = _s; + } + function get1() public returns (string memory r) { + return s; + } + function get2() public returns (string memory r) { + r = s; + } +} +// ---- +// set(string): 0x20, 5, "Julia" -> +// get1() -> 0x20, 5, "Julia" +// get2() -> 0x20, 5, "Julia" +// s() -> 0x20, 5, "Julia" diff --git a/examples/test/semanticTests/strings_return_string/return_string_standard_input.json b/examples/test/semanticTests/strings_return_string/return_string_standard_input.json new file mode 100644 index 00000000..8fe2dc71 --- /dev/null +++ b/examples/test/semanticTests/strings_return_string/return_string_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + }, + "unicode_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d, and \ud83d\ude08\";\n }\n function g() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d,\\\n and \ud83d\ude08\";\n }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n" + }, + "empty_string_input.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return \"\";\n }\n function g(string calldata msg) public pure returns (string memory) {\n return msg;\n }\n function h(string calldata msg, uint256 v) public pure returns (string memory, uint256) {\n return (msg, v);\n }\n // Adjusting order of input/output intentionally.\n function i(string calldata msg1, uint256 v, string calldata msg2) public pure returns (string memory, string memory, uint256) {\n return (msg1, msg2, v);\n }\n function j(string calldata msg1, uint256 v) public pure returns (string memory, string memory, uint256) {\n return (msg1, \"\", v);\n }\n}\n// ----\n// f() -> 0x20, 0\n// g(string): 0x20, 0, \"\" -> 0x20, 0\n// g(string): 0x20, 0 -> 0x20, 0\n// h(string,uint256): 0x40, 0x888, 0, \"\" -> 0x40, 0x0888, 0\n// h(string,uint256): 0x40, 0x888, 0 -> 0x40, 0x0888, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// i(string,uint256,string): 0x60, 0x888, 0x60, 0 -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0, \"\" -> 0x60, 0x80, 0x0888, 0, 0\n// j(string,uint256): 0x40, 0x888, 0 -> 0x60, 0x80, 0x0888, 0, 0\n" + }, + "empty_storage_string.sol": { + "content": "contract C {\n\n string uninitializedString;\n string emptyString = \"\";\n string nonEmptyString = \"This is a non empty string\";\n string nonEmptyString2 = \"Another string\";\n bytes uninitializedBytes;\n bytes emptyBytes = \"\";\n error EmptyError(string);\n event EmptyEvent(string);\n\n function f() public returns (string memory) {\n return uninitializedString;\n }\n\n function g() public returns (string memory, string memory) {\n return (uninitializedString, emptyString);\n }\n\n function h() public returns (string memory, string memory) {\n return (uninitializedString, nonEmptyString);\n }\n\n function i() public returns (string memory, string memory) {\n return (nonEmptyString, emptyString);\n }\n\n function j(string calldata _s) public returns (string memory) {\n return _s;\n }\n\n function k() public returns (string memory) {\n nonEmptyString2 = \"\";\n return nonEmptyString2;\n }\n\n function l(string calldata _s) public returns (bytes memory) {\n return abi.encode(_s);\n }\n\n function m() public returns (string memory) {\n bytes memory b = abi.encode(emptyString);\n return string(b);\n }\n\n function n() public {\n revert EmptyError(uninitializedString);\n }\n\n function o() public {\n emit EmptyEvent(emptyString);\n }\n\n function p() public {\n emit EmptyEvent(\"\");\n }\n\n function q() public returns (bytes memory) {\n return uninitializedBytes;\n }\n\n function r() public returns (bytes memory) {\n emptyBytes = abi.encode(\"\");\n return emptyBytes;\n }\n\n function s() public returns (bytes memory) {\n emptyBytes = abi.encode(uninitializedString);\n return emptyBytes;\n }\n\n function set(string calldata _s) public {\n nonEmptyString = _s;\n }\n\n function get() public returns (string memory) {\n return nonEmptyString;\n }\n}\n// ====\n// compileViaYul: also\n// ----\n// f() -> 0x20, 0\n// g() -> 0x40, 0x60, 0, 0\n// h() -> 0x40, 0x60, 0, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328\n// i() -> 0x40, 0x80, 0x1a, 38178759162904981154304545770567765692299154484752076569098748838215919075328, 0\n// j(string): 0x20, 0, \"\" -> 0x20, 0\n// k() -> 0x20, 0\n// l(string): 0x20, 0, \"\" -> 0x20, 0x40, 0x20, 0\n// m() -> 0x20, 0x40, 0x20, 0\n// n() -> FAILURE, hex\"d3f13430\", hex\"0000000000000000000000000000000000000000000000000000000000000020\", hex\"0000000000000000000000000000000000000000000000000000000000000000\"\n// o() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// p() ->\n// ~ emit EmptyEvent(string): 0x20, 0x00\n// q() -> 0x20, 0\n// r() -> 0x20, 0x40, 0x20, 0\n// s() -> 0x20, 0x40, 0x20, 0\n// set(string): 0x20, 0, \"\" ->\n// get() -> 0x20, 0\n" + }, + "return_string.sol": { + "content": "contract Main {\n string public s;\n function set(string calldata _s) external {\n s = _s;\n }\n function get1() public returns (string memory r) {\n return s;\n }\n function get2() public returns (string memory r) {\n r = s;\n }\n}\n// ----\n// set(string): 0x20, 5, \"Julia\" ->\n// get1() -> 0x20, 5, \"Julia\"\n// get2() -> 0x20, 5, \"Julia\"\n// s() -> 0x20, 5, \"Julia\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_string_escapes/string_escapes.sol b/examples/test/semanticTests/strings_string_escapes/string_escapes.sol new file mode 100644 index 00000000..ea178d64 --- /dev/null +++ b/examples/test/semanticTests/strings_string_escapes/string_escapes.sol @@ -0,0 +1,8 @@ +contract test { + function f() public pure returns (bytes32) { + bytes32 escapeCharacters = "\t\n\r\'\"\\"; + return escapeCharacters; + } +} +// ---- +// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/strings_string_escapes/string_escapes_standard_input.json b/examples/test/semanticTests/strings_string_escapes/string_escapes_standard_input.json new file mode 100644 index 00000000..ca0af241 --- /dev/null +++ b/examples/test/semanticTests/strings_string_escapes/string_escapes_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_unicode_escapes/unicode_escapes.sol b/examples/test/semanticTests/strings_unicode_escapes/unicode_escapes.sol new file mode 100644 index 00000000..401d8b61 --- /dev/null +++ b/examples/test/semanticTests/strings_unicode_escapes/unicode_escapes.sol @@ -0,0 +1,22 @@ +contract C { + function oneByteUTF8() public pure returns (string memory) { + return "aaa\u0024aaa"; // usdollar + } + + function twoBytesUTF8() public pure returns (string memory) { + return "aaa\u00A2aaa"; // cent + } + + function threeBytesUTF8() public pure returns (string memory) { + return "aaa\u20ACaaa"; // euro + } + + function combined() public pure returns (string memory) { + return "\u0024\u00A2\u20AC"; + } +} +// ---- +// oneByteUTF8() -> 0x20, 7, "aaa$aaa" +// twoBytesUTF8() -> 0x20, 8, "aaa\xc2\xa2aaa" +// threeBytesUTF8() -> 0x20, 9, "aaa\xe2\x82\xacaaa" +// combined() -> 0x20, 6, "$\xc2\xa2\xe2\x82\xac" diff --git a/examples/test/semanticTests/strings_unicode_escapes/unicode_escapes_standard_input.json b/examples/test/semanticTests/strings_unicode_escapes/unicode_escapes_standard_input.json new file mode 100644 index 00000000..3444f702 --- /dev/null +++ b/examples/test/semanticTests/strings_unicode_escapes/unicode_escapes_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/strings_unicode_string/unicode_string.sol b/examples/test/semanticTests/strings_unicode_string/unicode_string.sol new file mode 100644 index 00000000..e06556fb --- /dev/null +++ b/examples/test/semanticTests/strings_unicode_string/unicode_string.sol @@ -0,0 +1,12 @@ +contract C { + function f() public pure returns (string memory) { + return unicode"😃, 😭, and 😈"; + } + function g() public pure returns (string memory) { + return unicode"😃, 😭,\ + and 😈"; + } +} +// ---- +// f() -> 0x20, 0x14, "\xf0\x9f\x98\x83, \xf0\x9f\x98\xad, and \xf0\x9f\x98\x88" +// g() -> 0x20, 0x14, "\xf0\x9f\x98\x83, \xf0\x9f\x98\xad, and \xf0\x9f\x98\x88" diff --git a/examples/test/semanticTests/strings_unicode_string/unicode_string_standard_input.json b/examples/test/semanticTests/strings_unicode_string/unicode_string_standard_input.json new file mode 100644 index 00000000..36534dc2 --- /dev/null +++ b/examples/test/semanticTests/strings_unicode_string/unicode_string_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "string_escapes.sol": { + "content": "contract test {\n function f() public pure returns (bytes32) {\n bytes32 escapeCharacters = \"\\t\\n\\r\\'\\\"\\\\\";\n return escapeCharacters;\n }\n}\n// ----\n// f() -> 0x090a0d27225c0000000000000000000000000000000000000000000000000000\n" + }, + "unicode_escapes.sol": { + "content": "contract C {\n function oneByteUTF8() public pure returns (string memory) {\n return \"aaa\\u0024aaa\"; // usdollar\n }\n\n function twoBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u00A2aaa\"; // cent\n }\n\n function threeBytesUTF8() public pure returns (string memory) {\n return \"aaa\\u20ACaaa\"; // euro\n }\n\n function combined() public pure returns (string memory) {\n return \"\\u0024\\u00A2\\u20AC\";\n }\n}\n// ----\n// oneByteUTF8() -> 0x20, 7, \"aaa$aaa\"\n// twoBytesUTF8() -> 0x20, 8, \"aaa\\xc2\\xa2aaa\"\n// threeBytesUTF8() -> 0x20, 9, \"aaa\\xe2\\x82\\xacaaa\"\n// combined() -> 0x20, 6, \"$\\xc2\\xa2\\xe2\\x82\\xac\"\n" + }, + "unicode_string.sol": { + "content": "contract C {\n function f() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d, and \ud83d\ude08\";\n }\n function g() public pure returns (string memory) {\n return unicode\"\ud83d\ude03, \ud83d\ude2d,\\\n and \ud83d\ude08\";\n }\n}\n// ----\n// f() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n// g() -> 0x20, 0x14, \"\\xf0\\x9f\\x98\\x83, \\xf0\\x9f\\x98\\xad, and \\xf0\\x9f\\x98\\x88\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct.sol b/examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct.sol new file mode 100644 index 00000000..f5f53cc4 --- /dev/null +++ b/examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct.sol @@ -0,0 +1,12 @@ +contract Test { + struct RecursiveStruct { + RecursiveStruct[] vals; + } + + function func() public pure { + RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ]; + assert(val[0].vals.length == 42); + } +} +// ---- +// func() -> diff --git a/examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct_standard_input.json b/examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct_standard_input.json new file mode 100644 index 00000000..c571ad84 --- /dev/null +++ b/examples/test/semanticTests/structs_array_of_recursive_struct/array_of_recursive_struct_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs.sol b/examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs.sol new file mode 100644 index 00000000..42514440 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs.sol @@ -0,0 +1,47 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 p1; + uint256[][2] a; + uint32 p2; + } + + struct S1 { + uint128 u; + S s; + } + + struct S2 { + S[2] array; + } + + function f1(S1 calldata c) internal returns(S1 calldata) { + return c; + } + + function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) { + S1 memory m = f1(c); + assert(m.s.a[0][0] == c.s.a[0][0]); + assert(m.s.a[1][1] == c.s.a[1][1]); + return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2); + } + + function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) { + S2 memory m = c; + assert(m.array[0].a[0][0] == c.array[0].a[0][0]); + assert(m.array[0].a[1][1] == c.array[0].a[1][1]); + return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2); + } + + function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) { + S memory m = c.s; + assert(m.a[0][0] == c.s.a[0][0]); + assert(m.a[1][1] == c.s.a[1][1]); + return (p, m.p1, m.a[0][0], m.a[1][1], m.p2); + } +} +// ---- +// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33 +// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33 +// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33 diff --git a/examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs_standard_input.json new file mode 100644 index 00000000..8a7ec1f4 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_nested_structs/calldata_nested_structs_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_nested_structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n struct S1 {\n uint128 u;\n S s;\n }\n\n struct S2 {\n S[2] array;\n }\n\n function f1(S1 calldata c) internal returns(S1 calldata) {\n return c;\n }\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S1 memory m = f1(c);\n assert(m.s.a[0][0] == c.s.a[0][0]);\n assert(m.s.a[1][1] == c.s.a[1][1]);\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n\n function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n S2 memory m = c;\n assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n }\n\n function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m = c.s;\n assert(m.a[0][0] == c.s.a[0][0]);\n assert(m.a[1][1] == c.s.a[1][1]);\n return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct.sol b/examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct.sol new file mode 100644 index 00000000..418f9e93 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256 b; + } + + function f(S calldata s) external pure returns (uint256 a, uint256 b) { + a = s.a; + b = s.b; + } +} +// ---- +// f((uint256,uint256)): 42, 23 -> 42, 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct_standard_input.json new file mode 100644 index 00000000..9f412893 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct/calldata_struct_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints.sol new file mode 100644 index 00000000..5bdd1b42 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints.sol @@ -0,0 +1,19 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256 b; + } + + function f(uint256 a, S calldata s, uint256 b) + external + pure + returns (uint256, uint256, uint256, uint256) + { + return (a, s.a, s.b, b); + } +} +// ---- +// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints_standard_input.json new file mode 100644 index 00000000..54732f15 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_and_ints/calldata_struct_and_ints_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member.sol new file mode 100644 index 00000000..34d2bf47 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + + +contract C { + struct S { + uint256 a; + uint256[2] b; + uint256 c; + } + + function f(S calldata s) + external + pure + returns (uint256 a, uint256 b0, uint256 b1, uint256 c) + { + a = s.a; + b0 = s.b[0]; + b1 = s.b[1]; + c = s.c; + } +} +// ---- +// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member_standard_input.json new file mode 100644 index 00000000..07b7cb1f --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member/calldata_struct_array_member_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic.sol new file mode 100644 index 00000000..14f770a3 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +contract C { + struct S { + uint32 a; + uint256[] b; + uint64 c; + } + + function f(S calldata s) + external + pure + returns (uint32 a, uint256 b0, uint256 b1, uint64 c) + { + a = s.a; + b0 = s.b[0]; + b1 = s.b[1]; + c = s.c; + } +} +// ---- +// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic_standard_input.json new file mode 100644 index 00000000..a30ecf32 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_array_member_dynamic/calldata_struct_array_member_dynamic_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_nested_structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n struct S1 {\n uint128 u;\n S s;\n }\n\n struct S2 {\n S[2] array;\n }\n\n function f1(S1 calldata c) internal returns(S1 calldata) {\n return c;\n }\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S1 memory m = f1(c);\n assert(m.s.a[0][0] == c.s.a[0][0]);\n assert(m.s.a[1][1] == c.s.a[1][1]);\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n\n function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n S2 memory m = c;\n assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n }\n\n function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m = c.s;\n assert(m.a[0][0] == c.s.a[0][0]);\n assert(m.a[1][1] == c.s.a[1][1]);\n return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_as_memory_argument.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) {\n s.p1++;\n s.a[0][1]++;\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n return g(p1, c);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_struct_array_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint256[] b;\n uint64 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint32 a, uint256 b0, uint256 b1, uint64 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function.sol new file mode 100644 index 00000000..35d51d7b --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function.sol @@ -0,0 +1,27 @@ +pragma abicoder v2; + +struct S { + uint128 p1; + uint256[][2] a; + uint32 p2; +} +struct S1 { + uint128 u; + S s; +} + +library L { + function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) { + return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2); + } +} + +contract C { + + function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) { + return L.f(c, p); + } +} +// ---- +// library: L +// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function_standard_input.json new file mode 100644 index 00000000..80588671 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_as_argument_of_lib_function/calldata_struct_as_argument_of_lib_function_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument.sol new file mode 100644 index 00000000..c43e6fb1 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 p1; + uint256[][2] a; + uint32 p2; + } + + function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) { + s.p1++; + s.a[0][1]++; + return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2); + } + + function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) { + return g(p1, c); + } +} +// ---- +// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument_standard_input.json new file mode 100644 index 00000000..eadbef04 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_as_memory_argument/calldata_struct_as_memory_argument_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_nested_structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n struct S1 {\n uint128 u;\n S s;\n }\n\n struct S2 {\n S[2] array;\n }\n\n function f1(S1 calldata c) internal returns(S1 calldata) {\n return c;\n }\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S1 memory m = f1(c);\n assert(m.s.a[0][0] == c.s.a[0][0]);\n assert(m.s.a[1][1] == c.s.a[1][1]);\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n\n function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n S2 memory m = c;\n assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n }\n\n function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m = c.s;\n assert(m.a[0][0] == c.s.a[0][0]);\n assert(m.a[1][1] == c.s.a[1][1]);\n return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_as_memory_argument.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) {\n s.p1++;\n s.a[0][1]++;\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n return g(p1, c);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member.sol new file mode 100644 index 00000000..cc528805 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member.sol @@ -0,0 +1,26 @@ +pragma abicoder v2; + +contract C { + struct S { + uint64 a; + uint64 b; + } + struct S1 { + uint256 a; + S s; + uint256 c; + } + + function f(S1 calldata s1) + external + pure + returns (uint256 a, uint64 b0, uint64 b1, uint256 c) + { + a = s1.a; + b0 = s1.s.a; + b1 = s1.s.b; + c = s1.c; + } +} +// ---- +// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member_standard_input.json new file mode 100644 index 00000000..4790d2a0 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member/calldata_struct_struct_member_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic.sol new file mode 100644 index 00000000..7c84a096 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic.sol @@ -0,0 +1,26 @@ +pragma abicoder v2; + +contract C { + struct S { + uint64 a; + bytes b; + } + struct S1 { + uint256 a; + S s; + uint256 c; + } + + function f(S1 calldata s1) + external + pure + returns (uint256 a, uint64 b0, bytes1 b1, uint256 c) + { + a = s1.a; + b0 = s1.s.a; + b1 = s1.s.b[0]; + c = s1.c; + } +} +// ---- +// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, "ab" -> 42, 1, "a", 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic_standard_input.json new file mode 100644 index 00000000..e29f7f35 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_struct_member_dynamic/calldata_struct_struct_member_dynamic_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory.sol new file mode 100644 index 00000000..3aeb0dcb --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; + uint256 b; + bytes2 c; + } + + function f(S calldata s) external pure returns (uint256, uint256, bytes1) { + S memory m = s; + return (m.a, m.b, m.c[1]); + } +} +// ---- +// f((uint256,uint256,bytes2)): 42, 23, "ab" -> 42, 23, "b" diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory_standard_input.json new file mode 100644 index 00000000..e5d2c800 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory/calldata_struct_to_memory_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_nested_structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n struct S1 {\n uint128 u;\n S s;\n }\n\n struct S2 {\n S[2] array;\n }\n\n function f1(S1 calldata c) internal returns(S1 calldata) {\n return c;\n }\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S1 memory m = f1(c);\n assert(m.s.a[0][0] == c.s.a[0][0]);\n assert(m.s.a[1][1] == c.s.a[1][1]);\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n\n function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n S2 memory m = c;\n assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n }\n\n function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m = c.s;\n assert(m.a[0][0] == c.s.a[0][0]);\n assert(m.a[1][1] == c.s.a[1][1]);\n return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_as_memory_argument.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) {\n s.p1++;\n s.a[0][1]++;\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n return g(p1, c);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_struct_array_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint256[] b;\n uint64 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint32 a, uint256 b0, uint256 b1, uint64 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_nested_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n s.p1++;\n assert(s.p1 != c.p1);\n s.a[0][1]++;\n assert(s.a[0][1] != c.a[0][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n bytes2 c;\n }\n\n function f(S calldata s) external pure returns (uint256, uint256, bytes1) {\n S memory m = s;\n return (m.a, m.b, m.c[1]);\n }\n}\n// ----\n// f((uint256,uint256,bytes2)): 42, 23, \"ab\" -> 42, 23, \"b\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment.sol new file mode 100644 index 00000000..51617980 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 p1; + uint256[][2] a; + uint32 p2; + } + + function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) { + S memory m; + uint32 p2; + (p2, m) = (p1, c); + m.p1++; + m.a[0][1]++; + return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2); + } +} +// ---- +// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment_standard_input.json new file mode 100644 index 00000000..120f4ea8 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_to_memory_tuple_assignment/calldata_struct_to_memory_tuple_assignment_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage.sol new file mode 100644 index 00000000..6b56a73c --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage.sol @@ -0,0 +1,19 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; + uint64 b; + bytes2 c; + } + + uint[153] r; + S s; + + function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) { + s = c; + return (s.a, s.b, s.c[1]); + } +} +// ---- +// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, "ab", 1 -> 42, 23, "b" diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage_standard_input.json new file mode 100644 index 00000000..015cca0a --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_to_storage/calldata_struct_to_storage_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory.sol new file mode 100644 index 00000000..b7b3058b --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; + uint256[2] b; + uint256 c; + } + + function f(S calldata c) + external + pure + returns (uint256, uint256, uint256, uint256) + { + S memory m = c; + return (m.a, m.b[0], m.b[1], m.c); + } +} +// ---- +// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory_standard_input.json new file mode 100644 index 00000000..416d4043 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_array_to_memory/calldata_struct_with_array_to_memory_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory.sol new file mode 100644 index 00000000..3fa7a33f --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory.sol @@ -0,0 +1,20 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; + bytes b; + uint256 c; + } + + function f(S calldata c) + external + pure + returns (uint256, bytes1, bytes1, uint256) + { + S memory m = c; + return (m.a, m.b[0], m.b[1], m.c); + } +} +// ---- +// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, "ab" -> 42, "a", "b", 23 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory_standard_input.json new file mode 100644 index 00000000..e83dc469 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_bytes_to_memory/calldata_struct_with_bytes_to_memory_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory.sol new file mode 100644 index 00000000..b3c7f469 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 p1; + uint256[][2] a; + uint32 p2; + } + function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) { + S memory s = c; + assert(s.a[0][0] == c.a[0][0]); + assert(s.a[1][1] == c.a[1][1]); + s.p1++; + assert(s.p1 != c.p1); + s.a[0][1]++; + assert(s.a[0][1] != c.a[0][1]); + return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2); + } +} +// ---- +// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory_standard_input.json new file mode 100644 index 00000000..d6cfca77 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_memory/calldata_struct_with_nested_array_to_memory_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_nested_structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n struct S1 {\n uint128 u;\n S s;\n }\n\n struct S2 {\n S[2] array;\n }\n\n function f1(S1 calldata c) internal returns(S1 calldata) {\n return c;\n }\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S1 memory m = f1(c);\n assert(m.s.a[0][0] == c.s.a[0][0]);\n assert(m.s.a[1][1] == c.s.a[1][1]);\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n\n function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n S2 memory m = c;\n assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n }\n\n function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m = c.s;\n assert(m.a[0][0] == c.s.a[0][0]);\n assert(m.a[1][1] == c.s.a[1][1]);\n return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_as_memory_argument.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) {\n s.p1++;\n s.a[0][1]++;\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n return g(p1, c);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_struct_array_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint256[] b;\n uint64 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint32 a, uint256 b0, uint256 b1, uint64 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_nested_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n s.p1++;\n assert(s.p1 != c.p1);\n s.a[0][1]++;\n assert(s.a[0][1] != c.a[0][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage.sol b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage.sol new file mode 100644 index 00000000..27674861 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 p1; + uint256[][2] a; + uint32 p2; + } + S s; + function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) { + s = c; + assert(s.a[0][0] == c.a[0][0]); + assert(s.a[1][1] == c.a[1][1]); + return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2); + } +} +// ---- +// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88 +// gas irOptimized: 202902 +// gas legacy: 207376 +// gas legacyOptimized: 203583 diff --git a/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage_standard_input.json new file mode 100644 index 00000000..694c066c --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_struct_with_nested_array_to_storage/calldata_struct_with_nested_array_to_storage_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs.sol b/examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs.sol new file mode 100644 index 00000000..b7307713 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs.sol @@ -0,0 +1,26 @@ +pragma abicoder v2; + + +contract C { + struct S1 { + uint256 a; + uint256 b; + } + struct S2 { + uint256 a; + } + + function f(S1 calldata s1, S2 calldata s2, S1 calldata s3) + external + pure + returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e) + { + a = s1.a; + b = s1.b; + c = s2.a; + d = s3.a; + e = s3.b; + } +} +// ---- +// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5 diff --git a/examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs_standard_input.json b/examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs_standard_input.json new file mode 100644 index 00000000..5dbd15c1 --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_calldata_structs/calldata_structs_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested.sol b/examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested.sol new file mode 100644 index 00000000..633c4c7b --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested.sol @@ -0,0 +1,11 @@ +pragma abicoder v2; + +contract C { + struct S2 { uint256 b; } + struct S { uint256 a; S2[] children; } + function f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) { + return (s.children.length, s.a, s.children[0].b, s.children[1].b); + } +} +// ---- +// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42 diff --git a/examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested_standard_input.json b/examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested_standard_input.json new file mode 100644 index 00000000..71d6603d --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_dynamic_nested/dynamic_nested_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded.sol b/examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded.sol new file mode 100644 index 00000000..0dfa2cea --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded.sol @@ -0,0 +1,10 @@ +pragma abicoder v2; + +contract C { + struct S { uint256[] a; } + function f(S calldata s) external pure returns (uint256 a, uint256 b, uint256 c) { + return (s.a.length, s.a[0], s.a[1]); + } +} +// ---- +// f((uint256[])): 32, 32, 2, 42, 23 -> 2, 42, 23 diff --git a/examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded_standard_input.json b/examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded_standard_input.json new file mode 100644 index 00000000..ddbb32be --- /dev/null +++ b/examples/test/semanticTests/structs_calldata_dynamically_encoded/dynamically_encoded_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "calldata_struct_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint64 b;\n bytes2 c;\n }\n\n uint[153] r;\n S s;\n\n function f(uint32 a, S calldata c, uint256 b) external returns (uint256, uint256, bytes1) {\n s = c;\n return (s.a, s.b, s.c[1]);\n }\n}\n// ----\n// f(uint32,(uint256,uint64,bytes2),uint256): 1, 42, 23, \"ab\", 1 -> 42, 23, \"b\"\n" + }, + "calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(S calldata s) external pure returns (uint256 a, uint256 b) {\n a = s.a;\n b = s.b;\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "calldata_struct_to_memory_tuple_assignment.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m;\n uint32 p2;\n (p2, m) = (p1, c);\n m.p1++;\n m.a[0][1]++;\n return (p2, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_structs.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n }\n\n function f(S1 calldata s1, S2 calldata s2, S1 calldata s3)\n external\n pure\n returns (uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n {\n a = s1.a;\n b = s1.b;\n c = s2.a;\n d = s3.a;\n e = s3.b;\n }\n}\n// ----\n// f((uint256,uint256),(uint256),(uint256,uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "calldata_struct_and_ints.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f(uint256 a, S calldata s, uint256 b)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n return (a, s.a, s.b, b);\n }\n}\n// ----\n// f(uint256,(uint256,uint256),uint256): 1, 2, 3, 4 -> 1, 2, 3, 4\n" + }, + "dynamic_nested.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S2 { uint256 b; }\n\tstruct S { uint256 a; S2[] children; }\n\tfunction f(S calldata s) external pure returns (uint256, uint256, uint256, uint256) {\n\t\treturn (s.children.length, s.a, s.children[0].b, s.children[1].b);\n\t}\n}\n// ----\n// f((uint256,(uint256)[])): 32, 17, 64, 2, 23, 42 -> 2, 17, 23, 42\n" + }, + "calldata_struct_as_argument_of_lib_function.sol": { + "content": "pragma abicoder v2;\n\nstruct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n}\nstruct S1 {\n uint128 u;\n S s;\n}\n\nlibrary L {\n function f(S1 memory m, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n}\n\ncontract C {\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n return L.f(c, p);\n }\n}\n// ----\n// library: L\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_with_nested_array_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n S s;\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88\n// gas irOptimized: 202902\n// gas legacy: 207376\n// gas legacyOptimized: 203583\n" + }, + "calldata_struct_struct_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n bytes b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, bytes1 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b[0];\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,bytes),uint256)): 0x20, 42, 0x60, 23, 1, 0x40, 2, \"ab\" -> 42, 1, \"a\", 23\n" + }, + "calldata_struct_with_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, uint256, uint256, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_array_member.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S {\n uint256 a;\n uint256[2] b;\n uint256 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint256 a, uint256 b0, uint256 b1, uint256 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint256,uint256[2],uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_bytes_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bytes b;\n uint256 c;\n }\n\n function f(S calldata c)\n external\n pure\n returns (uint256, bytes1, bytes1, uint256)\n {\n S memory m = c;\n return (m.a, m.b[0], m.b[1], m.c);\n }\n}\n// ----\n// f((uint256,bytes,uint256)): 0x20, 42, 0x60, 23, 2, \"ab\" -> 42, \"a\", \"b\", 23\n" + }, + "calldata_struct_struct_member.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint64 a;\n uint64 b;\n }\n struct S1 {\n uint256 a;\n S s;\n uint256 c;\n }\n\n function f(S1 calldata s1)\n external\n pure\n returns (uint256 a, uint64 b0, uint64 b1, uint256 c)\n {\n a = s1.a;\n b0 = s1.s.a;\n b1 = s1.s.b;\n c = s1.c;\n }\n}\n// ----\n// f((uint256,(uint64,uint64),uint256)): 42, 1, 2, 23 -> 42, 1, 2, 23\n" + }, + "calldata_nested_structs.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n struct S1 {\n uint128 u;\n S s;\n }\n\n struct S2 {\n S[2] array;\n }\n\n function f1(S1 calldata c) internal returns(S1 calldata) {\n return c;\n }\n\n function f(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S1 memory m = f1(c);\n assert(m.s.a[0][0] == c.s.a[0][0]);\n assert(m.s.a[1][1] == c.s.a[1][1]);\n return (p, m.s.p1, m.s.a[0][0], m.s.a[1][1], m.s.p2);\n }\n\n function g(S2 calldata c) external returns(uint128, uint256, uint256, uint32) {\n S2 memory m = c;\n assert(m.array[0].a[0][0] == c.array[0].a[0][0]);\n assert(m.array[0].a[1][1] == c.array[0].a[1][1]);\n return (m.array[1].p1, m.array[1].a[0][0], m.array[1].a[1][1], m.array[1].p2);\n }\n\n function h(S1 calldata c, uint32 p) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory m = c.s;\n assert(m.a[0][0] == c.s.a[0][0]);\n assert(m.a[1][1] == c.s.a[1][1]);\n return (p, m.p1, m.a[0][0], m.a[1][1], m.p2);\n }\n}\n// ----\n// f((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n// g(((uint128,uint256[][2],uint32)[2])): 0x20, 0x20, 0x40, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 22, 1, 2, 33\n// h((uint128,(uint128,uint256[][2],uint32)),uint32): 0x40, 44, 11, 0x40, 22, 0x60, 33, 0x40, 0x40, 2, 1, 2 -> 44, 22, 1, 2, 33\n" + }, + "calldata_struct_as_memory_argument.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n\n function g(uint32 p1, S memory s) internal returns(uint32, uint128, uint256, uint256, uint32) {\n s.p1++;\n s.a[0][1]++;\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n return g(p1, c);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_struct_array_member_dynamic.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint256[] b;\n uint64 c;\n }\n\n function f(S calldata s)\n external\n pure\n returns (uint32 a, uint256 b0, uint256 b1, uint64 c)\n {\n a = s.a;\n b0 = s.b[0];\n b1 = s.b[1];\n c = s.c;\n }\n}\n// ----\n// f((uint32,uint256[],uint64)): 0x20, 42, 0x60, 23, 2, 1, 2 -> 42, 1, 2, 23\n" + }, + "calldata_struct_with_nested_array_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 p1;\n uint256[][2] a;\n uint32 p2;\n }\n function f(uint32 p1, S calldata c) external returns(uint32, uint128, uint256, uint256, uint32) {\n S memory s = c;\n assert(s.a[0][0] == c.a[0][0]);\n assert(s.a[1][1] == c.a[1][1]);\n s.p1++;\n assert(s.p1 != c.p1);\n s.a[0][1]++;\n assert(s.a[0][1] != c.a[0][1]);\n return (p1, s.p1, s.a[0][0], s.a[1][1], s.p2);\n }\n}\n// ----\n// f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 78, 1, 2, 88\n" + }, + "calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n uint256 b;\n bytes2 c;\n }\n\n function f(S calldata s) external pure returns (uint256, uint256, bytes1) {\n S memory m = s;\n return (m.a, m.b, m.c[1]);\n }\n}\n// ----\n// f((uint256,uint256,bytes2)): 42, 23, \"ab\" -> 42, 23, \"b\"\n" + }, + "dynamically_encoded.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n\tstruct S { uint256[] a; }\n\tfunction f(S calldata s) external pure returns (uint256 a, uint256 b, uint256 c) {\n\t return (s.a.length, s.a[0], s.a[1]);\n\t}\n}\n// ----\n// f((uint256[])): 32, 32, 2, 42, 23 -> 2, 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory.sol b/examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory.sol new file mode 100644 index 00000000..8ec31a5c --- /dev/null +++ b/examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory.sol @@ -0,0 +1,28 @@ +contract CopyTest { + struct Tree { + Tree[] children; + } + + Tree storageTree; + Tree[] children; + + constructor() { + for (uint i = 0; i < 2; i++) + storageTree.children.push(); + for (uint i = 0; i < 23; i++) + storageTree.children[0].children.push(); + for (uint i = 0; i < 42; i++) + storageTree.children[1].children.push(); + } + + function run() public returns (uint256, uint256, uint256) { + Tree memory memoryTree; + memoryTree = storageTree; + return (memoryTree.children.length, memoryTree.children[0].children.length, memoryTree.children[1].children.length); + } +} +// ---- +// run() -> 2, 23, 42 +// gas irOptimized: 192828 +// gas legacy: 185730 +// gas legacyOptimized: 184457 diff --git a/examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory_standard_input.json b/examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory_standard_input.json new file mode 100644 index 00000000..d1dd8092 --- /dev/null +++ b/examples/test/semanticTests/structs_conversion_recursive_storage_memory/recursive_storage_memory_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "recursive_storage_memory.sol": { + "content": "contract CopyTest {\n struct Tree {\n Tree[] children;\n }\n\n Tree storageTree;\n Tree[] children;\n\n constructor() {\n for (uint i = 0; i < 2; i++)\n storageTree.children.push();\n for (uint i = 0; i < 23; i++)\n storageTree.children[0].children.push();\n for (uint i = 0; i < 42; i++)\n storageTree.children[1].children.push();\n }\n\n function run() public returns (uint256, uint256, uint256) {\n Tree memory memoryTree;\n memoryTree = storageTree;\n return (memoryTree.children.length, memoryTree.children[0].children.length, memoryTree.children[1].children.length);\n }\n}\n// ----\n// run() -> 2, 23, 42\n// gas irOptimized: 192828\n// gas legacy: 185730\n// gas legacyOptimized: 184457\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex.sol b/examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex.sol new file mode 100644 index 00000000..d14bff96 --- /dev/null +++ b/examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex.sol @@ -0,0 +1,50 @@ +contract CopyTest { + struct Tree { + uint256 data; + Tree[] children; + } + Tree storageTree; + Tree childStorageTree; + + constructor() { + storageTree.data = 0x42; + for (uint i = 0; i < 2; i++) + storageTree.children.push(childStorageTree); + storageTree.children[0].data = 0x4200; + storageTree.children[1].data = 0x4201; + for (uint i = 0; i < 3; i++) + storageTree.children[0].children.push(childStorageTree); + for (uint i = 0; i < 3; i++) + storageTree.children[0].children[i].data = 0x420000 + i; + for (uint i = 0; i < 4; i++) + storageTree.children[1].children.push(childStorageTree); + for (uint i = 0; i < 4; i++) + storageTree.children[1].children[i].data = 0x420100 + i; + } + + function countData(Tree memory tree) internal returns (uint256 c) { + c = 1; + for (uint i = 0; i < tree.children.length; i++) { + c += countData(tree.children[i]); + } + } + + function copyFromTree(Tree memory tree, uint256[] memory data, uint256 offset) internal returns (uint256) { + data[offset++] = tree.data; + for (uint i = 0; i < tree.children.length; i++) { + offset = copyFromTree(tree.children[i], data, offset); + } + return offset; + } + + function run() public returns (uint256[] memory) { + Tree memory memoryTree; + memoryTree = storageTree; + uint256 length = countData(memoryTree); + uint256[] memory result = new uint256[](length); + copyFromTree(memoryTree, result, 0); + return result; + } +} +// ---- +// run() -> 0x20, 10, 0x42, 0x4200, 0x420000, 0x420001, 0x420002, 0x4201, 0x420100, 0x420101, 0x420102, 0x420103 diff --git a/examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex_standard_input.json b/examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex_standard_input.json new file mode 100644 index 00000000..5b077a0e --- /dev/null +++ b/examples/test/semanticTests/structs_conversion_recursive_storage_memory_complex/recursive_storage_memory_complex_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "recursive_storage_memory.sol": { + "content": "contract CopyTest {\n struct Tree {\n Tree[] children;\n }\n\n Tree storageTree;\n Tree[] children;\n\n constructor() {\n for (uint i = 0; i < 2; i++)\n storageTree.children.push();\n for (uint i = 0; i < 23; i++)\n storageTree.children[0].children.push();\n for (uint i = 0; i < 42; i++)\n storageTree.children[1].children.push();\n }\n\n function run() public returns (uint256, uint256, uint256) {\n Tree memory memoryTree;\n memoryTree = storageTree;\n return (memoryTree.children.length, memoryTree.children[0].children.length, memoryTree.children[1].children.length);\n }\n}\n// ----\n// run() -> 2, 23, 42\n// gas irOptimized: 192828\n// gas legacy: 185730\n// gas legacyOptimized: 184457\n" + }, + "recursive_storage_memory_complex.sol": { + "content": "contract CopyTest {\n struct Tree {\n uint256 data;\n Tree[] children;\n }\n Tree storageTree;\n Tree childStorageTree;\n\n constructor() {\n storageTree.data = 0x42;\n for (uint i = 0; i < 2; i++)\n storageTree.children.push(childStorageTree);\n storageTree.children[0].data = 0x4200;\n storageTree.children[1].data = 0x4201;\n for (uint i = 0; i < 3; i++)\n storageTree.children[0].children.push(childStorageTree);\n for (uint i = 0; i < 3; i++)\n storageTree.children[0].children[i].data = 0x420000 + i;\n for (uint i = 0; i < 4; i++)\n storageTree.children[1].children.push(childStorageTree);\n for (uint i = 0; i < 4; i++)\n storageTree.children[1].children[i].data = 0x420100 + i;\n }\n\n function countData(Tree memory tree) internal returns (uint256 c) {\n c = 1;\n for (uint i = 0; i < tree.children.length; i++) {\n c += countData(tree.children[i]);\n }\n }\n\n function copyFromTree(Tree memory tree, uint256[] memory data, uint256 offset) internal returns (uint256) {\n data[offset++] = tree.data;\n for (uint i = 0; i < tree.children.length; i++) {\n offset = copyFromTree(tree.children[i], data, offset);\n }\n return offset;\n }\n\n function run() public returns (uint256[] memory) {\n Tree memory memoryTree;\n memoryTree = storageTree;\n uint256 length = countData(memoryTree);\n uint256[] memory result = new uint256[](length);\n copyFromTree(memoryTree, result, 0);\n return result;\n }\n}\n// ----\n// run() -> 0x20, 10, 0x42, 0x4200, 0x420000, 0x420001, 0x420002, 0x4201, 0x420100, 0x420101, 0x420102, 0x420103\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping.sol b/examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping.sol new file mode 100644 index 00000000..037ff206 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping.sol @@ -0,0 +1,43 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + m[7] = S({b: "foo", a: a, u: 7}); + } + + mapping (uint => S) m; + S s; + + function to_state() public returns (S memory) { + s = m[7]; + return s; + } + + function to_storage() public returns (S memory) { + S storage sLocal = s; + sLocal = m[7]; + return sLocal; + } + + function to_memory() public returns (S memory) { + return m[7]; + } + +} +// ---- +// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121282 +// gas legacy: 122977 +// gas legacyOptimized: 121652 +// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping_standard_input.json b/examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping_standard_input.json new file mode 100644 index 00000000..bf7a740c --- /dev/null +++ b/examples/test/semanticTests/structs_copy_from_mapping/copy_from_mapping_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_from_storage/copy_from_storage.sol b/examples/test/semanticTests/structs_copy_from_storage/copy_from_storage.sol new file mode 100644 index 00000000..b3d73045 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_from_storage/copy_from_storage.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; +// Example from https://github.com/ethereum/solidity/issues/12558 +struct S { + uint x; +} + +contract C { + S sStorage; + constructor() { + sStorage.x = 13; + } + + function f() external returns (S[] memory) { + S[] memory sMemory = new S[](1); + + sMemory[0] = sStorage; + + return sMemory; + } +} +// ---- +// f() -> 0x20, 1, 13 diff --git a/examples/test/semanticTests/structs_copy_from_storage/copy_from_storage_standard_input.json b/examples/test/semanticTests/structs_copy_from_storage/copy_from_storage_standard_input.json new file mode 100644 index 00000000..7f06dddf --- /dev/null +++ b/examples/test/semanticTests/structs_copy_from_storage/copy_from_storage_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage.sol b/examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage.sol new file mode 100644 index 00000000..600eb35a --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage.sol @@ -0,0 +1,95 @@ +pragma abicoder v2; + +struct S { uint value; } + +contract Test { + S[][] a; + S[] b; + + constructor() { + a.push(); + a[0].push(S(1)); + a[0].push(S(2)); + a[0].push(S(3)); + + b.push(S(4)); + b.push(S(5)); + b.push(S(6)); + b.push(S(7)); + } + + function test1() external returns (bool) { + a.push(); + a[1] = b; + + assert(a.length == 2); + assert(a[0].length == 3); + assert(a[1].length == 4); + assert(a[1][0].value == 4); + assert(a[1][1].value == 5); + assert(a[1][2].value == 6); + assert(a[1][3].value == 7); + + return true; + } + + function test2() external returns (bool) { + S[][] memory temp = new S[][](2); + + temp = a; + + assert(temp.length == 2); + assert(temp[0].length == 3); + assert(temp[1].length == 4); + assert(temp[1][0].value == 4); + assert(temp[1][1].value == 5); + assert(temp[1][2].value == 6); + assert(temp[1][3].value == 7); + + return true; + } + + function test3() external returns (bool) { + S[][] memory temp = new S[][](2); + + temp[0] = a[0]; + temp[1] = a[1]; + + assert(temp.length == 2); + assert(temp[0].length == 3); + assert(temp[1].length == 4); + assert(temp[1][0].value == 4); + assert(temp[1][1].value == 5); + assert(temp[1][2].value == 6); + assert(temp[1][3].value == 7); + + return true; + } + + function test4() external returns (bool) { + S[][] memory temp = new S[][](2); + + temp[0] = a[0]; + temp[1] = b; + + assert(temp.length == 2); + assert(temp[0].length == 3); + assert(temp[1].length == 4); + assert(temp[1][0].value == 4); + assert(temp[1][1].value == 5); + assert(temp[1][2].value == 6); + assert(temp[1][3].value == 7); + + return true; + } +} +// ==== +// EVMVersion: >homestead +// ---- +// test1() -> true +// gas irOptimized: 152965 +// gas legacy: 153010 +// gas legacyOptimized: 152636 +// test2() -> true +// test3() -> true +// test4() -> true diff --git a/examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage_standard_input.json b/examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage_standard_input.json new file mode 100644 index 00000000..52980205 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_array_from_storage/copy_struct_array_from_storage_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory.sol b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory.sol new file mode 100644 index 00000000..6c22c71d --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + function test(S calldata s) public returns (S memory) { + return s; + } +} +// ---- +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11 +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23 diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory_standard_input.json b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory_standard_input.json new file mode 100644 index 00000000..44f919bf --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_memory/copy_struct_with_nested_array_from_calldata_to_memory_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage.sol b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage.sol new file mode 100644 index 00000000..dcf2a3a2 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage.sol @@ -0,0 +1,21 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + S s; + + function test(S calldata src) public { + s = src; + + require(s.x[0] == 3); + require(s.y.length == 2); + require(s.y[0] == 7); + require(s.y[1] == 11); + } +} +// ---- +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage_standard_input.json b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage_standard_input.json new file mode 100644 index 00000000..15dc2741 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_calldata_to_storage/copy_struct_with_nested_array_from_calldata_to_storage_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory.sol b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory.sol new file mode 100644 index 00000000..3d132641 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + function test(S memory s) public returns (S memory r) { + return r; + } +} +// ---- +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0 +// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0 diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory_standard_input.json b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory_standard_input.json new file mode 100644 index 00000000..e93225b5 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_memory_to_memory/copy_struct_with_nested_array_from_memory_to_memory_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + }, + "struct_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n struct X {\n uint32 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34));\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "copy_struct_with_nested_array_from_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S memory s) public returns (S memory r) {\n return r;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage.sol b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage.sol new file mode 100644 index 00000000..880b7433 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage.sol @@ -0,0 +1,26 @@ +contract C { + struct S { + uint8[1] x; + uint8[] y; + } + + S src; + S dst; + + constructor() { + src.x = [3]; + src.y.push(7); + src.y.push(11); + } + + function test() public { + dst = src; + + require(dst.x[0] == 3); + require(dst.y.length == 2); + require(dst.y[0] == 7); + require(dst.y[1] == 11); + } +} +// ---- +// test() diff --git a/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage_standard_input.json b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage_standard_input.json new file mode 100644 index 00000000..1254cdd4 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_struct_with_nested_array_from_storage_to_storage/copy_struct_with_nested_array_from_storage_to_storage_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping.sol b/examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping.sol new file mode 100644 index 00000000..7188e1be --- /dev/null +++ b/examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping.sol @@ -0,0 +1,51 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + m[7] = S({b: "foo", a: a, u: 7}); + } + + mapping (uint => S) m; + S s; + + function to_state() public returns (S memory) { + s.b = m[7].b; + s.a = m[7].a; + s.u = m[7].u; + return s; + } + + function to_storage() public returns (S memory) { + S storage sLocal = s; + sLocal.b = m[7].b; + sLocal.a = m[7].a; + sLocal.u = m[7].u; + return sLocal; + } + + function to_memory() public returns (S memory) { + S memory sLocal; + sLocal.b = m[7].b; + sLocal.a = m[7].a; + sLocal.u = m[7].u; + return sLocal; + } + +} +// ---- +// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121454 +// gas legacy: 123114 +// gas legacyOptimized: 121659 +// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 diff --git a/examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping_standard_input.json b/examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping_standard_input.json new file mode 100644 index 00000000..06b9eb15 --- /dev/null +++ b/examples/test/semanticTests/structs_copy_substructures_from_mapping/copy_substructures_from_mapping_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping.sol b/examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping.sol new file mode 100644 index 00000000..54b659ba --- /dev/null +++ b/examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping.sol @@ -0,0 +1,65 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + S s; + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + s.b = "foo"; + s.a = a; + s.u = 21; + } + + mapping (uint => S) m; + + function from_memory() public returns (S memory) { + S memory sMemory = s; + m[0].b = sMemory.b; + m[0].a = sMemory.a; + m[0].u = sMemory.u; + return m[0]; + } + + function from_state() public returns (S memory) { + m[1].b = s.b; + m[1].a = s.a; + m[1].u = s.u; + return m[1]; + } + + function from_storage() public returns (S memory) { + S storage sLocal = s; + m[1].b = sLocal.b; + m[1].a = sLocal.a; + m[1].u = sLocal.u; + return m[1]; + } + + function from_calldata(S calldata sCalldata) public returns (S memory) { + m[2].b = sCalldata.b; + m[2].a = sCalldata.a; + m[2].u = sCalldata.u; + return m[2]; + } +} +// ---- +// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 122720 +// gas legacy: 130131 +// gas legacyOptimized: 128648 +// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121424 +// gas legacy: 123190 +// gas legacyOptimized: 121758 +// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 114852 +// gas legacy: 122423 +// gas legacyOptimized: 120698 diff --git a/examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping_standard_input.json b/examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping_standard_input.json new file mode 100644 index 00000000..2b1bdfbb --- /dev/null +++ b/examples/test/semanticTests/structs_copy_substructures_to_mapping/copy_substructures_to_mapping_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping.sol b/examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping.sol new file mode 100644 index 00000000..d020998b --- /dev/null +++ b/examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping.sol @@ -0,0 +1,62 @@ +pragma abicoder v2; + +contract C { + struct S { + bytes b; + uint16[] a; + uint16 u; + } + + S s; + constructor() { + uint16[] memory a = new uint16[](2); + a[0] = 13; + a[1] = 14; + + s.b = "foo"; + s.a = a; + s.u = 21; + } + + mapping (uint => S) m; + + function from_state() public returns (S memory) { + m[0] = s; + return m[0]; + } + + function from_storage() public returns (S memory) { + S storage sLocal = s; + m[1] = sLocal; + return m[1]; + } + + function from_memory() public returns (S memory) { + S memory sMemory = s; + m[2] = sMemory; + return m[2]; + } + + + function from_calldata(S calldata sCalldata) public returns (S memory) { + m[3] = sCalldata; + return m[3]; + } +} +// ---- +// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121515 +// gas legacy: 123051 +// gas legacyOptimized: 121704 +// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 121559 +// gas legacy: 123109 +// gas legacyOptimized: 121756 +// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 122740 +// gas legacy: 129996 +// gas legacyOptimized: 128644 +// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 +// gas irOptimized: 114824 +// gas legacy: 118207 +// gas legacyOptimized: 115327 diff --git a/examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping_standard_input.json b/examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping_standard_input.json new file mode 100644 index 00000000..d8f603ad --- /dev/null +++ b/examples/test/semanticTests/structs_copy_to_mapping/copy_to_mapping_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_delete_struct/delete_struct.sol b/examples/test/semanticTests/structs_delete_struct/delete_struct.sol new file mode 100644 index 00000000..39a1cf42 --- /dev/null +++ b/examples/test/semanticTests/structs_delete_struct/delete_struct.sol @@ -0,0 +1,48 @@ +contract test { + struct topStruct { + nestedStruct nstr; + uint topValue; + mapping (uint => uint) topMapping; + } + uint toDelete; + topStruct str; + struct nestedStruct { + uint nestedValue; + mapping (uint => bool) nestedMapping; + } + constructor() { + toDelete = 5; + str.topValue = 1; + str.topMapping[0] = 1; + str.topMapping[1] = 2; + + str.nstr.nestedValue = 2; + str.nstr.nestedMapping[0] = true; + str.nstr.nestedMapping[1] = false; + delete str; + delete toDelete; + } + function getToDelete() public returns (uint res){ + res = toDelete; + } + function getTopValue() public returns(uint topValue){ + topValue = str.topValue; + } + function getNestedValue() public returns(uint nestedValue){ + nestedValue = str.nstr.nestedValue; + } + function getTopMapping(uint index) public returns(uint ret) { + ret = str.topMapping[index]; + } + function getNestedMapping(uint index) public returns(bool ret) { + return str.nstr.nestedMapping[index]; + } +} +// ---- +// getToDelete() -> 0 +// getTopValue() -> 0 +// getNestedValue() -> 0 #mapping values should be the same# +// getTopMapping(uint256): 0 -> 1 +// getTopMapping(uint256): 1 -> 2 +// getNestedMapping(uint256): 0 -> true +// getNestedMapping(uint256): 1 -> false diff --git a/examples/test/semanticTests/structs_delete_struct/delete_struct_standard_input.json b/examples/test/semanticTests/structs_delete_struct/delete_struct_standard_input.json new file mode 100644 index 00000000..e75e105f --- /dev/null +++ b/examples/test/semanticTests/structs_delete_struct/delete_struct_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_event/event.sol b/examples/test/semanticTests/structs_event/event.sol new file mode 100644 index 00000000..5a96c7cf --- /dev/null +++ b/examples/test/semanticTests/structs_event/event.sol @@ -0,0 +1,16 @@ +pragma abicoder v2; + +struct Item {uint x;} +library L { + event Ev(Item); + function o() public { emit L.Ev(Item(1)); } +} +contract C { + function f() public { + L.o(); + } +} +// ---- +// library: L +// f() -> +// ~ emit Ev((uint256)): 0x01 diff --git a/examples/test/semanticTests/structs_event/event_standard_input.json b/examples/test/semanticTests/structs_event/event_standard_input.json new file mode 100644 index 00000000..86bf7824 --- /dev/null +++ b/examples/test/semanticTests/structs_event/event_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_function_type_copy/function_type_copy.sol b/examples/test/semanticTests/structs_function_type_copy/function_type_copy.sol new file mode 100644 index 00000000..6230d47f --- /dev/null +++ b/examples/test/semanticTests/structs_function_type_copy/function_type_copy.sol @@ -0,0 +1,43 @@ +pragma abicoder v2; +struct S { + function () external[] functions; +} + +contract C { + function f(function () external[] calldata functions) external returns (S memory) { + S memory s; + s.functions = functions; + return s; + } +} + +contract Test { + C immutable c = new C(); + + function test() external returns (bool) { + function() external[] memory functions = new function() external[](3); + + functions[0] = this.random1; + functions[1] = this.random2; + functions[2] = this.random3; + + S memory ret = c.f(functions); + + assert(ret.functions.length == 3); + assert(ret.functions[0] == this.random1); + assert(ret.functions[1] == this.random2); + assert(ret.functions[2] == this.random3); + + return true; + } + function random1() external { + } + function random2() external { + } + function random3() external { + } +} +// ==== +// EVMVersion: >homestead +// ---- +// test() -> true diff --git a/examples/test/semanticTests/structs_function_type_copy/function_type_copy_standard_input.json b/examples/test/semanticTests/structs_function_type_copy/function_type_copy_standard_input.json new file mode 100644 index 00000000..27ab620a --- /dev/null +++ b/examples/test/semanticTests/structs_function_type_copy/function_type_copy_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_global/global.sol b/examples/test/semanticTests/structs_global/global.sol new file mode 100644 index 00000000..05212253 --- /dev/null +++ b/examples/test/semanticTests/structs_global/global.sol @@ -0,0 +1,10 @@ +pragma abicoder v2; + +struct S { uint256 a; uint256 b; } +contract C { + function f(S calldata s) external pure returns (uint256, uint256) { + return (s.a, s.b); + } +} +// ---- +// f((uint256,uint256)): 42, 23 -> 42, 23 diff --git a/examples/test/semanticTests/structs_global/global_standard_input.json b/examples/test/semanticTests/structs_global/global_standard_input.json new file mode 100644 index 00000000..8f20745d --- /dev/null +++ b/examples/test/semanticTests/structs_global/global_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type.sol b/examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type.sol new file mode 100644 index 00000000..9434e404 --- /dev/null +++ b/examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type.sol @@ -0,0 +1,13 @@ +contract C { + struct s { + uint256 a; + uint256 b; + } + + function f() public returns (uint256) { + s[7][]; // This is only the type, should not have any effect + return 3; + } +} +// ---- +// f() -> 3 diff --git a/examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type_standard_input.json b/examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type_standard_input.json new file mode 100644 index 00000000..cc0b7ffe --- /dev/null +++ b/examples/test/semanticTests/structs_lone_struct_array_type/lone_struct_array_type_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + }, + "struct_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n struct X {\n uint32 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34));\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "copy_struct_with_nested_array_from_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S memory s) public returns (S memory r) {\n return r;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0\n" + }, + "struct_delete_storage_small.sol": { + "content": "contract C {\n struct S {\n uint64 y;\n uint64 z;\n }\n S s;\n function f() public returns (uint256 ret) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.y = 1; s.z = 2;\n delete s;\n assert(s.y == 0);\n assert(s.z == 0);\n assembly {\n ret := sload(s.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n" + }, + "packed_storage_structs_delete.sol": { + "content": "contract C {\n struct str { uint8 a; uint16 b; uint8 c; }\n uint8 x;\n uint16 y;\n str data;\n function test() public returns (uint) {\n x = 1;\n y = 2;\n data.a = 2;\n data.b = 0xabcd;\n data.c = 0xfa;\n if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa)\n return 2;\n delete y;\n delete data.b;\n if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa)\n return 3;\n delete x;\n delete data;\n return 1;\n }\n}\n// ----\n// test() -> 1\n// storageEmpty -> 1\n" + }, + "lone_struct_array_type.sol": { + "content": "contract C {\n struct s {\n uint256 a;\n uint256 b;\n }\n\n function f() public returns (uint256) {\n s[7][]; // This is only the type, should not have any effect\n return 3;\n }\n}\n// ----\n// f() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor.sol b/examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor.sol new file mode 100644 index 00000000..f844c08f --- /dev/null +++ b/examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor.sol @@ -0,0 +1,15 @@ +pragma abicoder v2; + +contract C { + struct S { + uint256 a; + bool x; + } + + function s() public returns(S memory) + { + return S({x: true, a: 8}); + } +} +// ---- +// s() -> 8, true diff --git a/examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor_standard_input.json b/examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor_standard_input.json new file mode 100644 index 00000000..cd063607 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_struct_named_constructor/memory_struct_named_constructor_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args.sol b/examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args.sol new file mode 100644 index 00000000..96b95699 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args.sol @@ -0,0 +1,31 @@ +contract Test { + struct S { + uint8 x; + uint16 y; + uint256 z; + } + + function test() public returns (uint256 x, uint256 y, uint256 z) { + S memory data = combine(1, 2, 3); + x = extract(data, 0); + y = extract(data, 1); + z = extract(data, 2); + } + + function extract(S memory s, uint256 which) internal returns (uint256 x) { + if (which == 0) return s.x; + else if (which == 1) return s.y; + else return s.z; + } + + function combine(uint8 x, uint16 y, uint256 z) + internal + returns (S memory s) + { + s.x = x; + s.y = y; + s.z = z; + } +} +// ---- +// test() -> 1, 2, 3 diff --git a/examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args_standard_input.json b/examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args_standard_input.json new file mode 100644 index 00000000..98d124cd --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_as_function_args/memory_structs_as_function_args_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested.sol b/examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested.sol new file mode 100644 index 00000000..e541fa97 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested.sol @@ -0,0 +1,41 @@ +contract Test { + struct S { + uint8 x; + uint16 y; + uint256 z; + } + struct X { + uint8 x; + S s; + } + + function test() + public + returns (uint256 a, uint256 x, uint256 y, uint256 z) + { + X memory d = combine(1, 2, 3, 4); + a = extract(d, 0); + x = extract(d, 1); + y = extract(d, 2); + z = extract(d, 3); + } + + function extract(X memory s, uint256 which) internal returns (uint256 x) { + if (which == 0) return s.x; + else if (which == 1) return s.s.x; + else if (which == 2) return s.s.y; + else return s.s.z; + } + + function combine(uint8 a, uint8 x, uint16 y, uint256 z) + internal + returns (X memory s) + { + s.x = a; + s.s.x = x; + s.s.y = y; + s.s.z = z; + } +} +// ---- +// test() -> 1, 2, 3, 4 diff --git a/examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested_standard_input.json b/examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested_standard_input.json new file mode 100644 index 00000000..b9670525 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_nested/memory_structs_nested_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load.sol b/examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load.sol new file mode 100644 index 00000000..6785f210 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load.sol @@ -0,0 +1,72 @@ +contract Test { + struct S { + uint8 x; + uint16 y; + uint256 z; + } + struct X { + uint8 x; + S s; + uint8[2] a; + } + X m_x; + + function load() + public + returns ( + uint256 a, + uint256 x, + uint256 y, + uint256 z, + uint256 a1, + uint256 a2 + ) + { + m_x.x = 1; + m_x.s.x = 2; + m_x.s.y = 3; + m_x.s.z = 4; + m_x.a[0] = 5; + m_x.a[1] = 6; + X memory d = m_x; + a = d.x; + x = d.s.x; + y = d.s.y; + z = d.s.z; + a1 = d.a[0]; + a2 = d.a[1]; + } + + function store() + public + returns ( + uint256 a, + uint256 x, + uint256 y, + uint256 z, + uint256 a1, + uint256 a2 + ) + { + X memory d; + d.x = 1; + d.s.x = 2; + d.s.y = 3; + d.s.z = 4; + d.a[0] = 5; + d.a[1] = 6; + m_x = d; + a = m_x.x; + x = m_x.s.x; + y = m_x.s.y; + z = m_x.s.z; + a1 = m_x.a[0]; + a2 = m_x.a[1]; + } +} +// ---- +// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 +// gas irOptimized: 110772 +// gas legacy: 112959 +// gas legacyOptimized: 110876 +// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 diff --git a/examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load_standard_input.json b/examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load_standard_input.json new file mode 100644 index 00000000..67197983 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_nested_load/memory_structs_nested_load_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write.sol b/examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write.sol new file mode 100644 index 00000000..fe319d19 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write.sol @@ -0,0 +1,55 @@ +contract Test { + struct S { + uint8 x; + uint16 y; + uint256 z; + uint8[2] a; + } + S[5] data; + + function testInit() + public + returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag) + { + S[2] memory d; + x = d[0].x; + y = d[0].y; + z = d[0].z; + a = d[0].a[1]; + flag = true; + } + + function testCopyRead() + public + returns (uint8 x, uint16 y, uint256 z, uint8 a) + { + data[2].x = 1; + data[2].y = 2; + data[2].z = 3; + data[2].a[1] = 4; + S memory s = data[2]; + x = s.x; + y = s.y; + z = s.z; + a = s.a[1]; + } + + function testAssign() + public + returns (uint8 x, uint16 y, uint256 z, uint8 a) + { + S memory s; + s.x = 1; + s.y = 2; + s.z = 3; + s.a[1] = 4; + x = s.x; + y = s.y; + z = s.z; + a = s.a[1]; + } +} +// ---- +// testInit() -> 0, 0, 0, 0, true +// testCopyRead() -> 1, 2, 3, 4 +// testAssign() -> 1, 2, 3, 4 diff --git a/examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write_standard_input.json b/examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write_standard_input.json new file mode 100644 index 00000000..60a07547 --- /dev/null +++ b/examples/test/semanticTests/structs_memory_structs_read_write/memory_structs_read_write_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy.sol b/examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy.sol new file mode 100644 index 00000000..d88797d5 --- /dev/null +++ b/examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy.sol @@ -0,0 +1,43 @@ +pragma abicoder v2; + +struct St0 { + bytes el0; +} +contract C { + function f() external returns (St0 memory) { + St0 memory x; + x.el0 = msg.data; + return x; + } + + function g() external returns (St0 memory) { + bytes memory temp = msg.data; + St0 memory x; + x.el0 = temp; + return x; + } + + function hashes() external returns (bytes4, bytes4) { + return (this.f.selector, this.g.selector); + } + + function large(uint256, uint256, uint256, uint256) external returns (St0 memory) { + St0 memory x; + x.el0 = msg.data; + return x; + } + + function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) { + bytes memory temp = msg.data; + St0 memory x; + x.el0 = temp; + return x; + } + +} +// ---- +// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000 +// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000 +// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000 +// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000 +// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy_standard_input.json b/examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy_standard_input.json new file mode 100644 index 00000000..af0adafd --- /dev/null +++ b/examples/test/semanticTests/structs_msg_data_to_struct_member_copy/msg_data_to_struct_member_copy_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation.sol b/examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation.sol new file mode 100644 index 00000000..648c962c --- /dev/null +++ b/examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation.sol @@ -0,0 +1,19 @@ +contract C { + struct I { + uint b; + uint c; + function(uint) external returns (uint) x; + } + struct S { + I a; + } + + function o(uint a) external returns(uint) { return a+1; } + + function f() external returns (uint) { + S memory s = S(I(1,2, this.o)); + return s.a.x(1); + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation_standard_input.json b/examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation_standard_input.json new file mode 100644 index 00000000..a433598b --- /dev/null +++ b/examples/test/semanticTests/structs_multislot_struct_allocation/multislot_struct_allocation_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation.sol b/examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation.sol new file mode 100644 index 00000000..0037d957 --- /dev/null +++ b/examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation.sol @@ -0,0 +1,16 @@ +contract C { + struct I { + uint b; + uint c; + } + struct S { + I a; + } + + function f() external returns (uint) { + S memory s = S(I(1,2)); + return s.a.b; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation_standard_input.json b/examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation_standard_input.json new file mode 100644 index 00000000..bcbf2893 --- /dev/null +++ b/examples/test/semanticTests/structs_nested_struct_allocation/nested_struct_allocation_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete.sol b/examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete.sol new file mode 100644 index 00000000..741b55f3 --- /dev/null +++ b/examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete.sol @@ -0,0 +1,25 @@ +contract C { + struct str { uint8 a; uint16 b; uint8 c; } + uint8 x; + uint16 y; + str data; + function test() public returns (uint) { + x = 1; + y = 2; + data.a = 2; + data.b = 0xabcd; + data.c = 0xfa; + if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa) + return 2; + delete y; + delete data.b; + if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa) + return 3; + delete x; + delete data; + return 1; + } +} +// ---- +// test() -> 1 +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete_standard_input.json b/examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete_standard_input.json new file mode 100644 index 00000000..5eb91f45 --- /dev/null +++ b/examples/test/semanticTests/structs_packed_storage_structs_delete/packed_storage_structs_delete_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + }, + "struct_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n struct X {\n uint32 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34));\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "copy_struct_with_nested_array_from_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S memory s) public returns (S memory r) {\n return r;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0\n" + }, + "struct_delete_storage_small.sol": { + "content": "contract C {\n struct S {\n uint64 y;\n uint64 z;\n }\n S s;\n function f() public returns (uint256 ret) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.y = 1; s.z = 2;\n delete s;\n assert(s.y == 0);\n assert(s.z == 0);\n assembly {\n ret := sload(s.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n" + }, + "packed_storage_structs_delete.sol": { + "content": "contract C {\n struct str { uint8 a; uint16 b; uint8 c; }\n uint8 x;\n uint16 y;\n str data;\n function test() public returns (uint) {\n x = 1;\n y = 2;\n data.a = 2;\n data.b = 0xabcd;\n data.c = 0xfa;\n if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa)\n return 2;\n delete y;\n delete data.b;\n if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa)\n return 3;\n delete x;\n delete data;\n return 1;\n }\n}\n// ----\n// test() -> 1\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2.sol b/examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2.sol new file mode 100644 index 00000000..65cfcf20 --- /dev/null +++ b/examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2.sol @@ -0,0 +1,24 @@ +contract C { + struct S { + uint16 v; + S[] x; + } + uint8[77] padding; + S s; + constructor() { + s.v = 21; + s.x.push(); s.x.push(); s.x.push(); + s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103; + } + function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) { + S storage sptr1 = s.x[0]; + S storage sptr2 = s.x[1]; + S storage sptr3 = s.x[2]; + uint256 slot1; uint256 slot2; uint256 slot3; + assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot } + delete s; + assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) } + } +} +// ---- +// f() -> 0, 0, 0, 0 diff --git a/examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2_standard_input.json b/examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2_standard_input.json new file mode 100644 index 00000000..24a66187 --- /dev/null +++ b/examples/test/semanticTests/structs_recursive_struct_2/recursive_struct_2_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_recursive_structs/recursive_structs.sol b/examples/test/semanticTests/structs_recursive_structs/recursive_structs.sol new file mode 100644 index 00000000..f8944f11 --- /dev/null +++ b/examples/test/semanticTests/structs_recursive_structs/recursive_structs.sol @@ -0,0 +1,18 @@ +contract C { + struct S { + S[] x; + } + S sstorage; + + function f() public returns (uint256) { + S memory s; + s.x = new S[](10); + delete s; + // TODO Uncomment after implemented. + // sstorage.x.push(); + delete sstorage; + return 1; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/structs_recursive_structs/recursive_structs_standard_input.json b/examples/test/semanticTests/structs_recursive_structs/recursive_structs_standard_input.json new file mode 100644 index 00000000..6a6cab4d --- /dev/null +++ b/examples/test/semanticTests/structs_recursive_structs/recursive_structs_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation.sol b/examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation.sol new file mode 100644 index 00000000..e45626d3 --- /dev/null +++ b/examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation.sol @@ -0,0 +1,12 @@ +contract C { + struct S { + uint a; + } + + function f() external returns (uint) { + S memory s = S(1); + return s.a; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation_standard_input.json b/examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation_standard_input.json new file mode 100644 index 00000000..3bb02497 --- /dev/null +++ b/examples/test/semanticTests/structs_simple_struct_allocation/simple_struct_allocation_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct.sol b/examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct.sol new file mode 100644 index 00000000..47b9a9ec --- /dev/null +++ b/examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct.sol @@ -0,0 +1,35 @@ +contract test { + struct testStruct { + uint256 m_value; + } + testStruct data1; + testStruct data2; + testStruct data3; + + constructor() { + data1.m_value = 2; + } + + function assign() + public + returns ( + uint256 ret_local, + uint256 ret_global, + uint256 ret_global3, + uint256 ret_global1 + ) + { + testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2 + data2 = data1; // should copy data. data2.m_value == 2 + + ret_local = x.m_value; // = 2 + ret_global = data2.m_value; // = 2 + + x.m_value = 3; + data3 = x; //should copy the data. data3.m_value == 3 + ret_global3 = data3.m_value; // = 3 + ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value + } +} +// ---- +// assign() -> 2, 2, 3, 3 diff --git a/examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct_standard_input.json b/examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct_standard_input.json new file mode 100644 index 00000000..01c97c77 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_assign_reference_to_struct/struct_assign_reference_to_struct_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested.sol b/examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested.sol new file mode 100644 index 00000000..7ce22e45 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested.sol @@ -0,0 +1,30 @@ +contract C { + struct X { + uint256 x1; + uint256 x2; + } + struct S { + uint256 s1; + uint256[3] s2; + X s3; + } + S s; + + constructor() { + uint256[3] memory s2; + s2[1] = 9; + s = S(1, s2, X(4, 5)); + } + + function get() + public + returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2) + { + s1 = s.s1; + s2 = s.s2; + x1 = s.s3.x1; + x2 = s.s3.x2; + } +} +// ---- +// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05 diff --git a/examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested_standard_input.json b/examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested_standard_input.json new file mode 100644 index 00000000..2cd1f833 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_constructor_nested/struct_constructor_nested_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete.sol b/examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete.sol new file mode 100644 index 00000000..e50265e5 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete.sol @@ -0,0 +1,39 @@ +contract c { + struct Struct { uint a; bytes data; uint b; } + Struct data1; + Struct data2; + function set(uint _a, bytes calldata _data, uint _b) external returns (bool) { + data1.a = _a; + data1.b = _b; + data1.data = _data; + return true; + } + function copy() public returns (bool) { + data1 = data2; + return true; + } + function del() public returns (bool) { + delete data1; + return true; + } + function test(uint256 i) public returns (bytes1) { + return data1.data[i]; + } +} +// ---- +// storageEmpty -> 1 +// set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true +// gas irOptimized: 133557 +// gas legacy: 134624 +// gas legacyOptimized: 133856 +// test(uint256): 32 -> "3" +// storageEmpty -> 0 +// copy() -> true +// storageEmpty -> 1 +// set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true +// gas irOptimized: 133557 +// gas legacy: 134624 +// gas legacyOptimized: 133856 +// storageEmpty -> 0 +// del() -> true +// storageEmpty -> 1 diff --git a/examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete_standard_input.json b/examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete_standard_input.json new file mode 100644 index 00000000..49a7ea0f --- /dev/null +++ b/examples/test/semanticTests/structs_struct_containing_bytes_copy_and_delete/struct_containing_bytes_copy_and_delete_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_copy/struct_copy.sol b/examples/test/semanticTests/structs_struct_copy/struct_copy.sol new file mode 100644 index 00000000..e148f81c --- /dev/null +++ b/examples/test/semanticTests/structs_struct_copy/struct_copy.sol @@ -0,0 +1,52 @@ +contract c { + struct Nested { + uint256 x; + uint256 y; + } + struct Struct { + uint256 a; + Nested nested; + uint256 c; + } + mapping(uint256 => Struct) data; + + function set(uint256 k) public returns (bool) { + data[k].a = 1; + data[k].nested.x = 3; + data[k].nested.y = 4; + data[k].c = 2; + return true; + } + + function copy(uint256 from, uint256 to) public returns (bool) { + data[to] = data[from]; + return true; + } + + function retrieve(uint256 k) + public + returns (uint256 a, uint256 x, uint256 y, uint256 c) + { + a = data[k].a; + x = data[k].nested.x; + y = data[k].nested.y; + c = data[k].c; + } +} +// ---- +// set(uint256): 7 -> true +// gas irOptimized: 109932 +// gas legacy: 110593 +// gas legacyOptimized: 110003 +// retrieve(uint256): 7 -> 1, 3, 4, 2 +// copy(uint256,uint256): 7, 8 -> true +// gas irOptimized: 118581 +// gas legacy: 119144 +// gas legacyOptimized: 118618 +// retrieve(uint256): 7 -> 1, 3, 4, 2 +// retrieve(uint256): 8 -> 1, 3, 4, 2 +// copy(uint256,uint256): 0, 7 -> true +// retrieve(uint256): 7 -> 0, 0, 0, 0 +// retrieve(uint256): 8 -> 1, 3, 4, 2 +// copy(uint256,uint256): 7, 8 -> true +// retrieve(uint256): 8 -> 0, 0, 0, 0 diff --git a/examples/test/semanticTests/structs_struct_copy/struct_copy_standard_input.json b/examples/test/semanticTests/structs_struct_copy/struct_copy_standard_input.json new file mode 100644 index 00000000..b6b6195b --- /dev/null +++ b/examples/test/semanticTests/structs_struct_copy/struct_copy_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local.sol b/examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local.sol new file mode 100644 index 00000000..6b8788d2 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local.sol @@ -0,0 +1,22 @@ +contract c { + struct Struct { + uint256 a; + uint256 b; + } + uint[75] r; + Struct data1; + Struct data2; + + function test() public returns (bool) { + data1.a = 1; + data1.b = 2; + Struct memory x = data1; + data2 = x; + return data2.a == data1.a && data2.b == data1.b; + } +} +// ---- +// test() -> true +// gas irOptimized: 109921 +// gas legacy: 110615 +// gas legacyOptimized: 109705 diff --git a/examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local_standard_input.json b/examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local_standard_input.json new file mode 100644 index 00000000..5350c031 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_copy_via_local/struct_copy_via_local_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_member/struct_delete_member.sol b/examples/test/semanticTests/structs_struct_delete_member/struct_delete_member.sol new file mode 100644 index 00000000..7f991f40 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_member/struct_delete_member.sol @@ -0,0 +1,19 @@ +contract test { + struct testStruct { + uint256 m_value; + } + testStruct data1; + + constructor() { + data1.m_value = 2; + } + + function deleteMember() public returns (uint256 ret_value) { + testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0 + x.m_value = 4; + delete x.m_value; + ret_value = data1.m_value; + } +} +// ---- +// deleteMember() -> 0 diff --git a/examples/test/semanticTests/structs_struct_delete_member/struct_delete_member_standard_input.json b/examples/test/semanticTests/structs_struct_delete_member/struct_delete_member_standard_input.json new file mode 100644 index 00000000..e3018a70 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_member/struct_delete_member_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage.sol b/examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage.sol new file mode 100644 index 00000000..31558cfb --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage.sol @@ -0,0 +1,21 @@ +contract C { + struct S { + uint256 x; + uint128 y; + uint32 z; + } + uint8 b = 23; + S s; + uint8 a = 17; + function f() public { + s.x = 42; s.y = 42; s.y = 42; + delete s; + assert(s.x == 0); + assert(s.y == 0); + assert(s.z == 0); + assert(b == 23); + assert(a == 17); + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage_standard_input.json b/examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage_standard_input.json new file mode 100644 index 00000000..c565270e --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage/struct_delete_storage_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small.sol b/examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small.sol new file mode 100644 index 00000000..57bf38e5 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small.sol @@ -0,0 +1,36 @@ +contract C { + struct S { + uint32 a; + S[] x; + } + S s; + function f() public returns (uint256 r1, uint256 r2, uint256 r3) { + assembly { + // 2 ** 150 - 1 + sstore(s.slot, 1427247692705959881058285969449495136382746623) + } + s.a = 1; + s.x.push(); s.x.push(); + S storage ptr1 = s.x[0]; + S storage ptr2 = s.x[1]; + assembly { + // 2 ** 150 - 1 + sstore(ptr1.slot, 1427247692705959881058285969449495136382746623) + sstore(ptr2.slot, 1427247692705959881058285969449495136382746623) + } + s.x[0].a = 2; s.x[1].a = 3; + delete s; + assert(s.a == 0); + assert(s.x.length == 0); + assembly { + r1 := sload(s.slot) + r2 := sload(ptr1.slot) + r3 := sload(ptr2.slot) + } + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0, 0, 0 +// gas irOptimized: 117101 diff --git a/examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small_standard_input.json b/examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small_standard_input.json new file mode 100644 index 00000000..0f43ffcf --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_nested_small/struct_delete_storage_nested_small_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small.sol b/examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small.sol new file mode 100644 index 00000000..046e4ec6 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small.sol @@ -0,0 +1,24 @@ +contract C { + struct S { + uint64 y; + uint64 z; + } + S s; + function f() public returns (uint256 ret) { + assembly { + // 2 ** 150 - 1 + sstore(s.slot, 1427247692705959881058285969449495136382746623) + } + s.y = 1; s.z = 2; + delete s; + assert(s.y == 0); + assert(s.z == 0); + assembly { + ret := sload(s.slot) + } + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small_standard_input.json b/examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small_standard_input.json new file mode 100644 index 00000000..cd740654 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_small/struct_delete_storage_small_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + }, + "struct_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n struct X {\n uint32 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34));\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "copy_struct_with_nested_array_from_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S memory s) public returns (S memory r) {\n return r;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0\n" + }, + "struct_delete_storage_small.sol": { + "content": "contract C {\n struct S {\n uint64 y;\n uint64 z;\n }\n S s;\n function f() public returns (uint256 ret) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.y = 1; s.z = 2;\n delete s;\n assert(s.y == 0);\n assert(s.z == 0);\n assembly {\n ret := sload(s.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array.sol b/examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array.sol new file mode 100644 index 00000000..cea11056 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array.sol @@ -0,0 +1,51 @@ +pragma abicoder v2; + +contract C { + struct S { + uint128 a; + uint256[] x; + uint240 b; + } + uint8 b = 23; + S s; + uint8 a = 17; + function f() public { + delete s; + s.x.push(42); s.x.push(42); s.x.push(42); + delete s; + assert(s.x.length == 0); + uint256[] storage x = s.x; + assembly { sstore(x.slot, 3) } + assert(s.x[0] == 0); + assert(s.x[1] == 0); + assert(s.x[2] == 0); + assert(b == 23); + assert(a == 17); + } + + function g() public { + delete s; + s.x.push(42); s.x.push(42); s.x.push(42); + s.a = 1; s.b = 2; + delete s.x; + assert(s.x.length == 0); + uint256[] storage x = s.x; + assembly { sstore(x.slot, 3) } + assert(s.x[0] == 0); + assert(s.x[1] == 0); + assert(s.x[2] == 0); + assert(b == 23); + assert(a == 17); + assert(s.a == 1); + assert(s.b == 2); + } +} +// ---- +// f() -> +// gas irOptimized: 113465 +// gas legacy: 113591 +// gas legacyOptimized: 113098 +// g() -> +// gas irOptimized: 118828 +// gas legacy: 118764 +// gas legacyOptimized: 118168 diff --git a/examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array_standard_input.json b/examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array_standard_input.json new file mode 100644 index 00000000..da6ece13 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_with_array/struct_delete_storage_with_array_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small.sol b/examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small.sol new file mode 100644 index 00000000..2345fea3 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small.sol @@ -0,0 +1,30 @@ +contract C { + struct S { + uint32 a; + uint32[3] b; + uint32[] x; + } + S s; + function f() public returns (uint256 ret) { + assembly { + // 2 ** 150 - 1 + sstore(s.slot, 1427247692705959881058285969449495136382746623) + } + s.a = 1; + s.b[0] = 2; s.b[1] = 3; + s.x.push(4); s.x.push(5); + delete s; + assert(s.a == 0); + assert(s.b[0] == 0); + assert(s.b[1] == 0); + assert(s.x.length == 0); + assembly { + ret := sload(s.slot) + } + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> 0 +// gas irOptimized: 111570 diff --git a/examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small_standard_input.json b/examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small_standard_input.json new file mode 100644 index 00000000..fd8769b6 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_storage_with_arrays_small/struct_delete_storage_with_arrays_small_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + }, + "struct_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n struct X {\n uint32 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34));\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "copy_struct_with_nested_array_from_memory_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S memory s) public returns (S memory r) {\n return r;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 0, 0x40, 0\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 0, 0x40, 0\n" + }, + "struct_delete_storage_small.sol": { + "content": "contract C {\n struct S {\n uint64 y;\n uint64 z;\n }\n S s;\n function f() public returns (uint256 ret) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.y = 1; s.z = 2;\n delete s;\n assert(s.y == 0);\n assert(s.z == 0);\n assembly {\n ret := sload(s.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n" + }, + "packed_storage_structs_delete.sol": { + "content": "contract C {\n struct str { uint8 a; uint16 b; uint8 c; }\n uint8 x;\n uint16 y;\n str data;\n function test() public returns (uint) {\n x = 1;\n y = 2;\n data.a = 2;\n data.b = 0xabcd;\n data.c = 0xfa;\n if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa)\n return 2;\n delete y;\n delete data.b;\n if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa)\n return 3;\n delete x;\n delete data;\n return 1;\n }\n}\n// ----\n// test() -> 1\n// storageEmpty -> 1\n" + }, + "lone_struct_array_type.sol": { + "content": "contract C {\n struct s {\n uint256 a;\n uint256 b;\n }\n\n function f() public returns (uint256) {\n s[7][]; // This is only the type, should not have any effect\n return 3;\n }\n}\n// ----\n// f() -> 3\n" + }, + "struct_delete_storage_with_arrays_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n uint32[3] b;\n uint32[] x;\n }\n S s;\n function f() public returns (uint256 ret) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.b[0] = 2; s.b[1] = 3;\n s.x.push(4); s.x.push(5);\n delete s;\n assert(s.a == 0);\n assert(s.b[0] == 0);\n assert(s.b[1] == 0);\n assert(s.x.length == 0);\n assembly {\n ret := sload(s.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0\n// gas irOptimized: 111570\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping.sol b/examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping.sol new file mode 100644 index 00000000..ae21f6f8 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping.sol @@ -0,0 +1,17 @@ +contract test { + struct testStruct { + uint256 m_value; + } + mapping(uint256 => testStruct) campaigns; + + constructor() { + campaigns[0].m_value = 2; + } + + function deleteIt() public returns (uint256) { + delete campaigns[0]; + return campaigns[0].m_value; + } +} +// ---- +// deleteIt() -> 0 diff --git a/examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping_standard_input.json b/examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping_standard_input.json new file mode 100644 index 00000000..13d02ef6 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_delete_struct_in_mapping/struct_delete_struct_in_mapping_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage.sol b/examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage.sol new file mode 100644 index 00000000..290c812c --- /dev/null +++ b/examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + +contract C { + struct S { + uint32 a; + uint128 b; + uint256 c; + } + + struct X { + uint256 a; + S s; + } + + uint[79] r; + X x; + + function f() external returns (uint32, uint128, uint256) { + X memory m = X(12, S(42, 23, 34)); + x = m; + return (x.s.a, x.s.b, x.s.c); + } +} +// ---- +// f() -> 42, 23, 34 diff --git a/examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage_standard_input.json b/examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage_standard_input.json new file mode 100644 index 00000000..dbe95713 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_memory_to_storage/struct_memory_to_storage_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr.sol b/examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr.sol new file mode 100644 index 00000000..0de21947 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr.sol @@ -0,0 +1,33 @@ +pragma abicoder v2; + +contract C { + struct S { + uint32 a; + uint128 b; + uint256 c; + function() internal returns (uint32) f; + } + + struct X { + uint256 a; + S s; + } + + uint[79] r; + X x; + + function f() external returns (uint32, uint128, uint256, uint32, uint32) { + X memory m = X(12, S(42, 23, 34, g)); + x = m; + return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f()); + } + + function g() internal returns (uint32) { + return x.s.a; + } +} +// ---- +// f() -> 42, 23, 34, 42, 42 +// gas irOptimized: 110682 +// gas legacy: 111990 +// gas legacyOptimized: 110546 diff --git a/examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr_standard_input.json b/examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr_standard_input.json new file mode 100644 index 00000000..85b091a8 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_memory_to_storage_function_ptr/struct_memory_to_storage_function_ptr_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor.sol b/examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor.sol new file mode 100644 index 00000000..f16f61e3 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor.sol @@ -0,0 +1,13 @@ +contract C { + struct S { + uint256 a; + bool x; + } + S public s; + + constructor() { + s = S({x: true, a: 1}); + } +} +// ---- +// s() -> 1, true diff --git a/examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor_standard_input.json b/examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor_standard_input.json new file mode 100644 index 00000000..ef8ed6df --- /dev/null +++ b/examples/test/semanticTests/structs_struct_named_constructor/struct_named_constructor_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_reference/struct_reference.sol b/examples/test/semanticTests/structs_struct_reference/struct_reference.sol new file mode 100644 index 00000000..79eeccbe --- /dev/null +++ b/examples/test/semanticTests/structs_struct_reference/struct_reference.sol @@ -0,0 +1,24 @@ +contract test { + struct s2 { + uint32 z; + mapping(uint8 => s2) recursive; + } + s2 data; + function check() public returns (bool ok) { + return data.z == 2 && + data.recursive[0].z == 3 && + data.recursive[0].recursive[1].z == 0 && + data.recursive[0].recursive[0].z == 1; + } + function set() public { + data.z = 2; + mapping(uint8 => s2) storage map = data.recursive; + s2 storage inner = map[0]; + inner.z = 3; + inner.recursive[0].z = inner.recursive[1].z + 1; + } +} +// ---- +// check() -> false +// set() -> +// check() -> true diff --git a/examples/test/semanticTests/structs_struct_reference/struct_reference_standard_input.json b/examples/test/semanticTests/structs_struct_reference/struct_reference_standard_input.json new file mode 100644 index 00000000..d4c20be0 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_reference/struct_reference_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_referencing/struct_referencing.sol b/examples/test/semanticTests/structs_struct_referencing/struct_referencing.sol new file mode 100644 index 00000000..93fad63b --- /dev/null +++ b/examples/test/semanticTests/structs_struct_referencing/struct_referencing.sol @@ -0,0 +1,58 @@ +pragma abicoder v2; +interface I { + struct S { uint a; } +} + +library L { + struct S { uint b; uint a; } + function f() public pure returns (S memory) { + S memory s; + s.a = 3; + return s; + } + function g() public pure returns (I.S memory) { + I.S memory s; + s.a = 4; + return s; + } + // argument-dependent lookup tests + function a(I.S memory) public pure returns (uint) { return 1; } + function a(S memory) public pure returns (uint) { return 2; } +} + +contract C is I { + function f() public pure returns (S memory) { + S memory s; + s.a = 1; + return s; + } + function g() public pure returns (I.S memory) { + I.S memory s; + s.a = 2; + return s; + } + function h() public pure returns (L.S memory) { + L.S memory s; + s.a = 5; + return s; + } + function x() public pure returns (L.S memory) { + return L.f(); + } + function y() public pure returns (I.S memory) { + return L.g(); + } + function a1() public pure returns (uint) { S memory s; return L.a(s); } + function a2() public pure returns (uint) { L.S memory s; return L.a(s); } +} +// ---- +// library: L +// f() -> 1 +// g() -> 2 +// f() -> 1 +// g() -> 2 +// h() -> 0, 5 +// x() -> 0, 3 +// y() -> 4 +// a1() -> 1 +// a2() -> 2 diff --git a/examples/test/semanticTests/structs_struct_referencing/struct_referencing_standard_input.json b/examples/test/semanticTests/structs_struct_referencing/struct_referencing_standard_input.json new file mode 100644 index 00000000..1bdc48ad --- /dev/null +++ b/examples/test/semanticTests/structs_struct_referencing/struct_referencing_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value.sol b/examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value.sol new file mode 100644 index 00000000..d4277618 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value.sol @@ -0,0 +1,26 @@ +contract C { + struct S { + uint256 x; + uint128 y; + uint32 z; + uint128[3] a1; + uint128[] a2; + } + uint8 b = 23; + S[] s; + uint8 a = 17; + function f() public { + s.push(); + assert(s[0].x == 0); + assert(s[0].y == 0); + assert(s[0].z == 0); + assert(s[0].a1[0] == 0); + assert(s[0].a1[1] == 0); + assert(s[0].a1[2] == 0); + assert(s[0].a2.length == 0); + assert(b == 23); + assert(a == 17); + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value_standard_input.json b/examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value_standard_input.json new file mode 100644 index 00000000..9fe353c5 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_push_zero_value/struct_storage_push_zero_value_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping.sol b/examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping.sol new file mode 100644 index 00000000..b77c696b --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping.sol @@ -0,0 +1,15 @@ +contract C { + struct S { + uint a; + } + S s; + mapping (uint => S) m; + + function f() external returns (bool) { + s.a = 12; + m[1] = s; + return m[1].a == 12; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping_standard_input.json b/examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping_standard_input.json new file mode 100644 index 00000000..e33cc05a --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_to_mapping/struct_storage_to_mapping_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory.sol b/examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory.sol new file mode 100644 index 00000000..26862fd0 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + +contract C { + struct S { + uint32 a; + uint128 b; + uint256 c; + } + struct X { + uint32 a; + S s; + } + + uint[79] arr; + X x = X(12, S(42, 23, 34)); + + function f() external returns (uint32, uint128, uint256) { + X memory m = x; + return (m.s.a, m.s.b, m.s.c); + } +} +// ---- +// f() -> 42, 23, 34 diff --git a/examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory_standard_input.json b/examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory_standard_input.json new file mode 100644 index 00000000..47d5a578 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_to_memory/struct_storage_to_memory_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + }, + "copy_struct_with_nested_array_from_calldata_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n function test(S calldata s) public returns (S memory) {\n return s;\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11 -> 0x20, 3, 0x40, 2, 7, 11\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 3, 17, 19, 23 -> 0x20, 3, 0x40, 3, 17, 19, 23\n" + }, + "copy_struct_array_from_storage.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint value; }\n\ncontract Test {\n S[][] a;\n S[] b;\n\n constructor() {\n a.push();\n a[0].push(S(1));\n a[0].push(S(2));\n a[0].push(S(3));\n\n b.push(S(4));\n b.push(S(5));\n b.push(S(6));\n b.push(S(7));\n }\n\n function test1() external returns (bool) {\n a.push();\n a[1] = b;\n\n assert(a.length == 2);\n assert(a[0].length == 3);\n assert(a[1].length == 4);\n assert(a[1][0].value == 4);\n assert(a[1][1].value == 5);\n assert(a[1][2].value == 6);\n assert(a[1][3].value == 7);\n\n return true;\n }\n\n function test2() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp = a;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test3() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = a[1];\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n\n function test4() external returns (bool) {\n S[][] memory temp = new S[][](2);\n\n temp[0] = a[0];\n temp[1] = b;\n\n assert(temp.length == 2);\n assert(temp[0].length == 3);\n assert(temp[1].length == 4);\n assert(temp[1][0].value == 4);\n assert(temp[1][1].value == 5);\n assert(temp[1][2].value == 6);\n assert(temp[1][3].value == 7);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test1() -> true\n// gas irOptimized: 152965\n// gas legacy: 153010\n// gas legacyOptimized: 152636\n// test2() -> true\n// test3() -> true\n// test4() -> true\n" + }, + "recursive_structs.sol": { + "content": "contract C {\n struct S {\n S[] x;\n }\n S sstorage;\n\n function f() public returns (uint256) {\n S memory s;\n s.x = new S[](10);\n delete s;\n // TODO Uncomment after implemented.\n // sstorage.x.push();\n delete sstorage;\n return 1;\n }\n}\n// ----\n// f() -> 1\n" + }, + "copy_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_state() public returns (S memory) {\n m[0] = s;\n return m[0];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1] = sLocal;\n return m[1];\n }\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[2] = sMemory;\n return m[2];\n }\n\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[3] = sCalldata;\n return m[3];\n }\n}\n// ----\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121515\n// gas legacy: 123051\n// gas legacyOptimized: 121704\n// from_storage() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121559\n// gas legacy: 123109\n// gas legacyOptimized: 121756\n// from_memory() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122740\n// gas legacy: 129996\n// gas legacyOptimized: 128644\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 21, 3, 0x666f6f0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114824\n// gas legacy: 118207\n// gas legacyOptimized: 115327\n" + }, + "array_of_recursive_struct.sol": { + "content": "contract Test {\n struct RecursiveStruct {\n RecursiveStruct[] vals;\n }\n\n function func() public pure {\n RecursiveStruct[1] memory val = [ RecursiveStruct(new RecursiveStruct[](42)) ];\n assert(val[0].vals.length == 42);\n }\n}\n// ----\n// func() ->\n" + }, + "struct_delete_struct_in_mapping.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n mapping(uint256 => testStruct) campaigns;\n\n constructor() {\n campaigns[0].m_value = 2;\n }\n\n function deleteIt() public returns (uint256) {\n delete campaigns[0];\n return campaigns[0].m_value;\n }\n}\n// ----\n// deleteIt() -> 0\n" + }, + "struct_assign_reference_to_struct.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n testStruct data2;\n testStruct data3;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function assign()\n public\n returns (\n uint256 ret_local,\n uint256 ret_global,\n uint256 ret_global3,\n uint256 ret_global1\n )\n {\n testStruct storage x = data1; //x is a reference data1.m_value == 2 as well as x.m_value = 2\n data2 = data1; // should copy data. data2.m_value == 2\n\n ret_local = x.m_value; // = 2\n ret_global = data2.m_value; // = 2\n\n x.m_value = 3;\n data3 = x; //should copy the data. data3.m_value == 3\n ret_global3 = data3.m_value; // = 3\n ret_global1 = data1.m_value; // = 3. Changed due to the assignment to x.m_value\n }\n}\n// ----\n// assign() -> 2, 2, 3, 3\n" + }, + "struct_storage_to_mapping.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n S s;\n mapping (uint => S) m;\n\n function f() external returns (bool) {\n s.a = 12;\n m[1] = s;\n return m[1].a == 12;\n }\n}\n// ----\n// f() -> true\n" + }, + "multislot_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n function(uint) external returns (uint) x;\n }\n struct S {\n I a;\n }\n\n function o(uint a) external returns(uint) { return a+1; }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2, this.o));\n return s.a.x(1);\n }\n}\n// ----\n// f() -> 2\n" + }, + "copy_substructures_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n S s;\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n s.b = \"foo\";\n s.a = a;\n s.u = 21;\n }\n\n mapping (uint => S) m;\n\n function from_memory() public returns (S memory) {\n S memory sMemory = s;\n m[0].b = sMemory.b;\n m[0].a = sMemory.a;\n m[0].u = sMemory.u;\n return m[0];\n }\n\n function from_state() public returns (S memory) {\n m[1].b = s.b;\n m[1].a = s.a;\n m[1].u = s.u;\n return m[1];\n }\n\n function from_storage() public returns (S memory) {\n S storage sLocal = s;\n m[1].b = sLocal.b;\n m[1].a = sLocal.a;\n m[1].u = sLocal.u;\n return m[1];\n }\n\n function from_calldata(S calldata sCalldata) public returns (S memory) {\n m[2].b = sCalldata.b;\n m[2].a = sCalldata.a;\n m[2].u = sCalldata.u;\n return m[2];\n }\n}\n// ----\n// from_memory() -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 122720\n// gas legacy: 130131\n// gas legacyOptimized: 128648\n// from_state() -> 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121424\n// gas legacy: 123190\n// gas legacyOptimized: 121758\n// from_calldata((bytes,uint16[],uint16)): 0x20, 0x60, 0xa0, 21, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14 -> 0x20, 0x60, 0xa0, 0x15, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 114852\n// gas legacy: 122423\n// gas legacyOptimized: 120698\n" + }, + "struct_constructor_nested.sol": { + "content": "contract C {\n struct X {\n uint256 x1;\n uint256 x2;\n }\n struct S {\n uint256 s1;\n uint256[3] s2;\n X s3;\n }\n S s;\n\n constructor() {\n uint256[3] memory s2;\n s2[1] = 9;\n s = S(1, s2, X(4, 5));\n }\n\n function get()\n public\n returns (uint256 s1, uint256[3] memory s2, uint256 x1, uint256 x2)\n {\n s1 = s.s1;\n s2 = s.s2;\n x1 = s.s3.x1;\n x2 = s.s3.x2;\n }\n}\n// ----\n// get() -> 0x01, 0x00, 0x09, 0x00, 0x04, 0x05\n" + }, + "struct_copy.sol": { + "content": "contract c {\n struct Nested {\n uint256 x;\n uint256 y;\n }\n struct Struct {\n uint256 a;\n Nested nested;\n uint256 c;\n }\n mapping(uint256 => Struct) data;\n\n function set(uint256 k) public returns (bool) {\n data[k].a = 1;\n data[k].nested.x = 3;\n data[k].nested.y = 4;\n data[k].c = 2;\n return true;\n }\n\n function copy(uint256 from, uint256 to) public returns (bool) {\n data[to] = data[from];\n return true;\n }\n\n function retrieve(uint256 k)\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 c)\n {\n a = data[k].a;\n x = data[k].nested.x;\n y = data[k].nested.y;\n c = data[k].c;\n }\n}\n// ----\n// set(uint256): 7 -> true\n// gas irOptimized: 109932\n// gas legacy: 110593\n// gas legacyOptimized: 110003\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// gas irOptimized: 118581\n// gas legacy: 119144\n// gas legacyOptimized: 118618\n// retrieve(uint256): 7 -> 1, 3, 4, 2\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 0, 7 -> true\n// retrieve(uint256): 7 -> 0, 0, 0, 0\n// retrieve(uint256): 8 -> 1, 3, 4, 2\n// copy(uint256,uint256): 7, 8 -> true\n// retrieve(uint256): 8 -> 0, 0, 0, 0\n" + }, + "delete_struct.sol": { + "content": "contract test {\n struct topStruct {\n nestedStruct nstr;\n uint topValue;\n mapping (uint => uint) topMapping;\n }\n uint toDelete;\n topStruct str;\n struct nestedStruct {\n uint nestedValue;\n mapping (uint => bool) nestedMapping;\n }\n constructor() {\n toDelete = 5;\n str.topValue = 1;\n str.topMapping[0] = 1;\n str.topMapping[1] = 2;\n\n str.nstr.nestedValue = 2;\n str.nstr.nestedMapping[0] = true;\n str.nstr.nestedMapping[1] = false;\n delete str;\n delete toDelete;\n }\n function getToDelete() public returns (uint res){\n res = toDelete;\n }\n function getTopValue() public returns(uint topValue){\n topValue = str.topValue;\n }\n function getNestedValue() public returns(uint nestedValue){\n nestedValue = str.nstr.nestedValue;\n }\n function getTopMapping(uint index) public returns(uint ret) {\n ret = str.topMapping[index];\n }\n function getNestedMapping(uint index) public returns(bool ret) {\n return str.nstr.nestedMapping[index];\n }\n}\n// ----\n// getToDelete() -> 0\n// getTopValue() -> 0\n// getNestedValue() -> 0 #mapping values should be the same#\n// getTopMapping(uint256): 0 -> 1\n// getTopMapping(uint256): 1 -> 2\n// getNestedMapping(uint256): 0 -> true\n// getNestedMapping(uint256): 1 -> false\n" + }, + "struct_storage_to_memory.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n struct X {\n uint32 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34));\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr.sol b/examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr.sol new file mode 100644 index 00000000..5ec25fb3 --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr.sol @@ -0,0 +1,29 @@ +pragma abicoder v2; + +contract C { + struct S { + uint32 a; + uint128 b; + uint256 c; + function() internal returns (uint32) f; + } + + struct X { + uint256 a; + S s; + } + + uint[79] arr; + X x = X(12, S(42, 23, 34, g)); + + function f() external returns (uint32, uint128, uint256, uint32, uint32) { + X memory m = x; + return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f()); + } + + function g() internal returns (uint32) { + return x.s.a; + } +} +// ---- +// f() -> 42, 23, 34, 42, 42 diff --git a/examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr_standard_input.json b/examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr_standard_input.json new file mode 100644 index 00000000..f4d6490f --- /dev/null +++ b/examples/test/semanticTests/structs_struct_storage_to_memory_function_ptr/struct_storage_to_memory_function_ptr_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + }, + "global.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 a; uint256 b; }\ncontract C {\n function f(S calldata s) external pure returns (uint256, uint256) {\n return (s.a, s.b);\n }\n}\n// ----\n// f((uint256,uint256)): 42, 23 -> 42, 23\n" + }, + "struct_memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256) {\n X memory m = X(12, S(42, 23, 34));\n x = m;\n return (x.s.a, x.s.b, x.s.c);\n }\n}\n// ----\n// f() -> 42, 23, 34\n" + }, + "simple_struct_allocation.sol": { + "content": "contract C {\n struct S {\n uint a;\n }\n\n function f() external returns (uint) {\n S memory s = S(1);\n return s.a;\n }\n}\n// ----\n// f() -> 1\n" + }, + "event.sol": { + "content": "pragma abicoder v2;\n\nstruct Item {uint x;}\nlibrary L {\n event Ev(Item);\n function o() public { emit L.Ev(Item(1)); }\n}\ncontract C {\n function f() public {\n L.o();\n }\n}\n// ----\n// library: L\n// f() ->\n// ~ emit Ev((uint256)): 0x01\n" + }, + "struct_containing_bytes_copy_and_delete.sol": { + "content": "contract c {\n struct Struct { uint a; bytes data; uint b; }\n Struct data1;\n Struct data2;\n function set(uint _a, bytes calldata _data, uint _b) external returns (bool) {\n data1.a = _a;\n data1.b = _b;\n data1.data = _data;\n return true;\n }\n function copy() public returns (bool) {\n data1 = data2;\n return true;\n }\n function del() public returns (bool) {\n delete data1;\n return true;\n }\n function test(uint256 i) public returns (bytes1) {\n return data1.data[i];\n }\n}\n// ----\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// test(uint256): 32 -> \"3\"\n// storageEmpty -> 0\n// copy() -> true\n// storageEmpty -> 1\n// set(uint256,bytes,uint256): 12, 0x60, 13, 33, \"12345678901234567890123456789012\", \"3\" -> true\n// gas irOptimized: 133557\n// gas legacy: 134624\n// gas legacyOptimized: 133856\n// storageEmpty -> 0\n// del() -> true\n// storageEmpty -> 1\n" + }, + "memory_structs_as_function_args.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n\n function test() public returns (uint256 x, uint256 y, uint256 z) {\n S memory data = combine(1, 2, 3);\n x = extract(data, 0);\n y = extract(data, 1);\n z = extract(data, 2);\n }\n\n function extract(S memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.y;\n else return s.z;\n }\n\n function combine(uint8 x, uint16 y, uint256 z)\n internal\n returns (S memory s)\n {\n s.x = x;\n s.y = y;\n s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3\n" + }, + "struct_referencing.sol": { + "content": "pragma abicoder v2;\ninterface I {\n struct S { uint a; }\n}\n\nlibrary L {\n struct S { uint b; uint a; }\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 3;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 4;\n return s;\n }\n // argument-dependent lookup tests\n function a(I.S memory) public pure returns (uint) { return 1; }\n function a(S memory) public pure returns (uint) { return 2; }\n}\n\ncontract C is I {\n function f() public pure returns (S memory) {\n S memory s;\n s.a = 1;\n return s;\n }\n function g() public pure returns (I.S memory) {\n I.S memory s;\n s.a = 2;\n return s;\n }\n function h() public pure returns (L.S memory) {\n L.S memory s;\n s.a = 5;\n return s;\n }\n function x() public pure returns (L.S memory) {\n return L.f();\n }\n function y() public pure returns (I.S memory) {\n return L.g();\n }\n function a1() public pure returns (uint) { S memory s; return L.a(s); }\n function a2() public pure returns (uint) { L.S memory s; return L.a(s); }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// f() -> 1\n// g() -> 2\n// h() -> 0, 5\n// x() -> 0, 3\n// y() -> 4\n// a1() -> 1\n// a2() -> 2\n" + }, + "struct_delete_member.sol": { + "content": "contract test {\n struct testStruct {\n uint256 m_value;\n }\n testStruct data1;\n\n constructor() {\n data1.m_value = 2;\n }\n\n function deleteMember() public returns (uint256 ret_value) {\n testStruct storage x = data1; //should not copy the data. data1.m_value == 2 but x.m_value = 0\n x.m_value = 4;\n delete x.m_value;\n ret_value = data1.m_value;\n }\n}\n// ----\n// deleteMember() -> 0\n" + }, + "recursive_struct_2.sol": { + "content": "contract C {\n struct S {\n uint16 v;\n S[] x;\n }\n uint8[77] padding;\n S s;\n constructor() {\n s.v = 21;\n s.x.push(); s.x.push(); s.x.push();\n s.x[0].v = 101; s.x[1].v = 102; s.x[2].v = 103;\n }\n function f() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n S storage sptr1 = s.x[0];\n S storage sptr2 = s.x[1];\n S storage sptr3 = s.x[2];\n uint256 slot1; uint256 slot2; uint256 slot3;\n assembly { slot1 := sptr1.slot slot2 := sptr2.slot slot3 := sptr3.slot }\n delete s;\n assembly { a := sload(s.slot) b := sload(slot1) c := sload(slot2) d := sload(slot3) }\n }\n}\n// ----\n// f() -> 0, 0, 0, 0\n" + }, + "struct_delete_storage.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n s.x = 42; s.y = 42; s.y = 42;\n delete s;\n assert(s.x == 0);\n assert(s.y == 0);\n assert(s.z == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "memory_structs_read_write.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n uint8[2] a;\n }\n S[5] data;\n\n function testInit()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a, bool flag)\n {\n S[2] memory d;\n x = d[0].x;\n y = d[0].y;\n z = d[0].z;\n a = d[0].a[1];\n flag = true;\n }\n\n function testCopyRead()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n data[2].x = 1;\n data[2].y = 2;\n data[2].z = 3;\n data[2].a[1] = 4;\n S memory s = data[2];\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n\n function testAssign()\n public\n returns (uint8 x, uint16 y, uint256 z, uint8 a)\n {\n S memory s;\n s.x = 1;\n s.y = 2;\n s.z = 3;\n s.a[1] = 4;\n x = s.x;\n y = s.y;\n z = s.z;\n a = s.a[1];\n }\n}\n// ----\n// testInit() -> 0, 0, 0, 0, true\n// testCopyRead() -> 1, 2, 3, 4\n// testAssign() -> 1, 2, 3, 4\n" + }, + "struct_copy_via_local.sol": { + "content": "contract c {\n struct Struct {\n uint256 a;\n uint256 b;\n }\n uint[75] r;\n Struct data1;\n Struct data2;\n\n function test() public returns (bool) {\n data1.a = 1;\n data1.b = 2;\n Struct memory x = data1;\n data2 = x;\n return data2.a == data1.a && data2.b == data1.b;\n }\n}\n// ----\n// test() -> true\n// gas irOptimized: 109921\n// gas legacy: 110615\n// gas legacyOptimized: 109705\n" + }, + "msg_data_to_struct_member_copy.sol": { + "content": "pragma abicoder v2;\n\nstruct St0 {\n bytes el0;\n}\ncontract C {\n function f() external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function g() external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n function hashes() external returns (bytes4, bytes4) {\n return (this.f.selector, this.g.selector);\n }\n\n function large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n St0 memory x;\n x.el0 = msg.data;\n return x;\n }\n\n function another_large(uint256, uint256, uint256, uint256) external returns (St0 memory) {\n bytes memory temp = msg.data;\n St0 memory x;\n x.el0 = temp;\n return x;\n }\n\n}\n// ----\n// f() -> 0x20, 0x20, 4, 0x26121ff000000000000000000000000000000000000000000000000000000000\n// g() -> 0x20, 0x20, 4, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// hashes() -> 0x26121ff000000000000000000000000000000000000000000000000000000000, 0xe2179b8e00000000000000000000000000000000000000000000000000000000\n// large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0xe02492f800000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n// another_large(uint256,uint256,uint256,uint256): 1, 2, 3, 4 -> 0x20, 0x20, 0x84, 0x2a46f85a00000000000000000000000000000000000000000000000000000000, 0x100000000000000000000000000000000000000000000000000000000, 0x200000000000000000000000000000000000000000000000000000000, 0x300000000000000000000000000000000000000000000000000000000, 0x400000000000000000000000000000000000000000000000000000000\n" + }, + "struct_storage_push_zero_value.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n uint128 y;\n uint32 z;\n uint128[3] a1;\n uint128[] a2;\n }\n uint8 b = 23;\n S[] s;\n uint8 a = 17;\n function f() public {\n s.push();\n assert(s[0].x == 0);\n assert(s[0].y == 0);\n assert(s[0].z == 0);\n assert(s[0].a1[0] == 0);\n assert(s[0].a1[1] == 0);\n assert(s[0].a1[2] == 0);\n assert(s[0].a2.length == 0);\n assert(b == 23);\n assert(a == 17);\n }\n}\n// ----\n// f() ->\n" + }, + "function_type_copy.sol": { + "content": "pragma abicoder v2;\nstruct S {\n function () external[] functions;\n}\n\ncontract C {\n function f(function () external[] calldata functions) external returns (S memory) {\n S memory s;\n s.functions = functions;\n return s;\n }\n}\n\ncontract Test {\n C immutable c = new C();\n\n function test() external returns (bool) {\n function() external[] memory functions = new function() external[](3);\n\n functions[0] = this.random1;\n functions[1] = this.random2;\n functions[2] = this.random3;\n\n S memory ret = c.f(functions);\n\n assert(ret.functions.length == 3);\n assert(ret.functions[0] == this.random1);\n assert(ret.functions[1] == this.random2);\n assert(ret.functions[2] == this.random3);\n\n return true;\n }\n function random1() external {\n }\n function random2() external {\n }\n function random3() external {\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// test() -> true\n" + }, + "memory_structs_nested_load.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n uint8[2] a;\n }\n X m_x;\n\n function load()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n m_x.x = 1;\n m_x.s.x = 2;\n m_x.s.y = 3;\n m_x.s.z = 4;\n m_x.a[0] = 5;\n m_x.a[1] = 6;\n X memory d = m_x;\n a = d.x;\n x = d.s.x;\n y = d.s.y;\n z = d.s.z;\n a1 = d.a[0];\n a2 = d.a[1];\n }\n\n function store()\n public\n returns (\n uint256 a,\n uint256 x,\n uint256 y,\n uint256 z,\n uint256 a1,\n uint256 a2\n )\n {\n X memory d;\n d.x = 1;\n d.s.x = 2;\n d.s.y = 3;\n d.s.z = 4;\n d.a[0] = 5;\n d.a[1] = 6;\n m_x = d;\n a = m_x.x;\n x = m_x.s.x;\n y = m_x.s.y;\n z = m_x.s.z;\n a1 = m_x.a[0];\n a2 = m_x.a[1];\n }\n}\n// ----\n// load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n// gas irOptimized: 110772\n// gas legacy: 112959\n// gas legacyOptimized: 110876\n// store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06\n" + }, + "struct_delete_storage_with_array.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint128 a;\n uint256[] x;\n uint240 b;\n }\n uint8 b = 23;\n S s;\n uint8 a = 17;\n function f() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n delete s;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n }\n\n function g() public {\n delete s;\n s.x.push(42); s.x.push(42); s.x.push(42);\n s.a = 1; s.b = 2;\n delete s.x;\n assert(s.x.length == 0);\n uint256[] storage x = s.x;\n assembly { sstore(x.slot, 3) }\n assert(s.x[0] == 0);\n assert(s.x[1] == 0);\n assert(s.x[2] == 0);\n assert(b == 23);\n assert(a == 17);\n assert(s.a == 1);\n assert(s.b == 2);\n }\n}\n// ----\n// f() ->\n// gas irOptimized: 113465\n// gas legacy: 113591\n// gas legacyOptimized: 113098\n// g() ->\n// gas irOptimized: 118828\n// gas legacy: 118764\n// gas legacyOptimized: 118168\n" + }, + "struct_memory_to_storage_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] r;\n X x;\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = X(12, S(42, 23, 34, g));\n x = m;\n return (x.s.a, x.s.b, x.s.c, x.s.f(), m.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n// gas irOptimized: 110682\n// gas legacy: 111990\n// gas legacyOptimized: 110546\n" + }, + "copy_struct_with_nested_array_from_storage_to_storage.sol": { + "content": "contract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S src;\n S dst;\n\n constructor() {\n src.x = [3];\n src.y.push(7);\n src.y.push(11);\n }\n\n function test() public {\n dst = src;\n\n require(dst.x[0] == 3);\n require(dst.y.length == 2);\n require(dst.y[0] == 7);\n require(dst.y[1] == 11);\n }\n}\n// ----\n// test()\n" + }, + "copy_struct_with_nested_array_from_calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[1] x;\n uint8[] y;\n }\n\n S s;\n\n function test(S calldata src) public {\n s = src;\n\n require(s.x[0] == 3);\n require(s.y.length == 2);\n require(s.y[0] == 7);\n require(s.y[1] == 11);\n }\n}\n// ----\n// test((uint8[1],uint8[])): 0x20, 3, 0x40, 2, 7, 11\n" + }, + "nested_struct_allocation.sol": { + "content": "contract C {\n struct I {\n uint b;\n uint c;\n }\n struct S {\n I a;\n }\n\n function f() external returns (uint) {\n S memory s = S(I(1,2));\n return s.a.b;\n }\n}\n// ----\n// f() -> 1\n" + }, + "memory_structs_nested.sol": { + "content": "contract Test {\n struct S {\n uint8 x;\n uint16 y;\n uint256 z;\n }\n struct X {\n uint8 x;\n S s;\n }\n\n function test()\n public\n returns (uint256 a, uint256 x, uint256 y, uint256 z)\n {\n X memory d = combine(1, 2, 3, 4);\n a = extract(d, 0);\n x = extract(d, 1);\n y = extract(d, 2);\n z = extract(d, 3);\n }\n\n function extract(X memory s, uint256 which) internal returns (uint256 x) {\n if (which == 0) return s.x;\n else if (which == 1) return s.s.x;\n else if (which == 2) return s.s.y;\n else return s.s.z;\n }\n\n function combine(uint8 a, uint8 x, uint16 y, uint256 z)\n internal\n returns (X memory s)\n {\n s.x = a;\n s.s.x = x;\n s.s.y = y;\n s.s.z = z;\n }\n}\n// ----\n// test() -> 1, 2, 3, 4\n" + }, + "struct_storage_to_memory_function_ptr.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint32 a;\n uint128 b;\n uint256 c;\n function() internal returns (uint32) f;\n }\n\n struct X {\n uint256 a;\n S s;\n }\n\n uint[79] arr;\n X x = X(12, S(42, 23, 34, g));\n\n function f() external returns (uint32, uint128, uint256, uint32, uint32) {\n X memory m = x;\n return (m.s.a, m.s.b, m.s.c, m.s.f(), x.s.f());\n }\n\n function g() internal returns (uint32) {\n return x.s.a;\n }\n}\n// ----\n// f() -> 42, 23, 34, 42, 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_structs/structs.sol b/examples/test/semanticTests/structs_structs/structs.sol new file mode 100644 index 00000000..96503fa1 --- /dev/null +++ b/examples/test/semanticTests/structs_structs/structs.sol @@ -0,0 +1,36 @@ +contract test { + struct s1 { + uint8 x; + bool y; + } + struct s2 { + uint32 z; + s1 s1data; + mapping(uint8 => s2) recursive; + } + s2 data; + function check() public returns (bool ok) { + return data.z == 1 && data.s1data.x == 2 && + data.s1data.y == true && + data.recursive[3].recursive[4].z == 5 && + data.recursive[4].recursive[3].z == 6 && + data.recursive[0].s1data.y == false && + data.recursive[4].z == 9; + } + function set() public { + data.z = 1; + data.s1data.x = 2; + data.s1data.y = true; + data.recursive[3].recursive[4].z = 5; + data.recursive[4].recursive[3].z = 6; + data.recursive[0].s1data.y = false; + data.recursive[4].z = 9; + } +} +// ---- +// check() -> false +// set() -> +// gas irOptimized: 134073 +// gas legacy: 135243 +// gas legacyOptimized: 134062 +// check() -> true diff --git a/examples/test/semanticTests/structs_structs/structs_standard_input.json b/examples/test/semanticTests/structs_structs/structs_standard_input.json new file mode 100644 index 00000000..ca51592a --- /dev/null +++ b/examples/test/semanticTests/structs_structs/structs_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + }, + "structs.sol": { + "content": "contract test {\n struct s1 {\n uint8 x;\n bool y;\n }\n struct s2 {\n uint32 z;\n s1 s1data;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 1 && data.s1data.x == 2 &&\n data.s1data.y == true &&\n data.recursive[3].recursive[4].z == 5 &&\n data.recursive[4].recursive[3].z == 6 &&\n data.recursive[0].s1data.y == false &&\n data.recursive[4].z == 9;\n }\n function set() public {\n data.z = 1;\n data.s1data.x = 2;\n data.s1data.y = true;\n data.recursive[3].recursive[4].z = 5;\n data.recursive[4].recursive[3].z = 6;\n data.recursive[0].s1data.y = false;\n data.recursive[4].z = 9;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// gas irOptimized: 134073\n// gas legacy: 135243\n// gas legacyOptimized: 134062\n// check() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct.sol b/examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct.sol new file mode 100644 index 00000000..7b51b59f --- /dev/null +++ b/examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct.sol @@ -0,0 +1,13 @@ +library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } } +contract C { + using D for D.s; + D.s public x; + function f(uint a) public returns (uint) { + x.a = 3; + return x.mul(a); + } +} +// ---- +// library: D +// f(uint256): 7 -> 0x15 +// x() -> 0x15 diff --git a/examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct_standard_input.json b/examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct_standard_input.json new file mode 100644 index 00000000..65e3027c --- /dev/null +++ b/examples/test/semanticTests/structs_using_for_function_on_struct/using_for_function_on_struct_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "memory_struct_named_constructor.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint256 a;\n bool x;\n }\n\n function s() public returns(S memory)\n {\n return S({x: true, a: 8});\n }\n}\n// ----\n// s() -> 8, true\n" + }, + "copy_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts = m[7];\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal = m[7];\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n\treturn m[7];\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121282\n// gas legacy: 122977\n// gas legacyOptimized: 121652\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_delete_storage_nested_small.sol": { + "content": "contract C {\n struct S {\n uint32 a;\n S[] x;\n }\n S s;\n function f() public returns (uint256 r1, uint256 r2, uint256 r3) {\n assembly {\n // 2 ** 150 - 1\n sstore(s.slot, 1427247692705959881058285969449495136382746623)\n }\n s.a = 1;\n s.x.push(); s.x.push();\n S storage ptr1 = s.x[0];\n S storage ptr2 = s.x[1];\n assembly {\n // 2 ** 150 - 1\n sstore(ptr1.slot, 1427247692705959881058285969449495136382746623)\n sstore(ptr2.slot, 1427247692705959881058285969449495136382746623)\n }\n s.x[0].a = 2; s.x[1].a = 3;\n delete s;\n assert(s.a == 0);\n assert(s.x.length == 0);\n assembly {\n r1 := sload(s.slot)\n r2 := sload(ptr1.slot)\n r3 := sload(ptr2.slot)\n }\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> 0, 0, 0\n// gas irOptimized: 117101\n" + }, + "copy_from_storage.sol": { + "content": "pragma abicoder v2;\n// Example from https://github.com/ethereum/solidity/issues/12558\nstruct S {\n uint x;\n}\n\ncontract C {\n S sStorage;\n constructor() {\n sStorage.x = 13;\n }\n\n function f() external returns (S[] memory) {\n S[] memory sMemory = new S[](1);\n\n sMemory[0] = sStorage;\n\n return sMemory;\n }\n}\n// ----\n// f() -> 0x20, 1, 13\n" + }, + "copy_substructures_from_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bytes b;\n uint16[] a;\n uint16 u;\n }\n\n constructor() {\n uint16[] memory a = new uint16[](2);\n a[0] = 13;\n a[1] = 14;\n\n m[7] = S({b: \"foo\", a: a, u: 7});\n }\n\n mapping (uint => S) m;\n S s;\n\n function to_state() public returns (S memory) {\n\ts.b = m[7].b;\n\ts.a = m[7].a;\n\ts.u = m[7].u;\n return s;\n }\n\n function to_storage() public returns (S memory) {\n S storage sLocal = s;\n\tsLocal.b = m[7].b;\n\tsLocal.a = m[7].a;\n\tsLocal.u = m[7].u;\n return sLocal;\n }\n\n function to_memory() public returns (S memory) {\n S memory sLocal;\n sLocal.b = m[7].b;\n sLocal.a = m[7].a;\n sLocal.u = m[7].u;\n\treturn sLocal;\n }\n\n}\n// ----\n// to_state() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// gas irOptimized: 121454\n// gas legacy: 123114\n// gas legacyOptimized: 121659\n// to_storage() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n// to_memory() -> 0x20, 0x60, 0xa0, 7, 3, 0x666F6F0000000000000000000000000000000000000000000000000000000000, 2, 13, 14\n" + }, + "struct_reference.sol": { + "content": "contract test {\n struct s2 {\n uint32 z;\n mapping(uint8 => s2) recursive;\n }\n s2 data;\n function check() public returns (bool ok) {\n return data.z == 2 &&\n data.recursive[0].z == 3 &&\n data.recursive[0].recursive[1].z == 0 &&\n data.recursive[0].recursive[0].z == 1;\n }\n function set() public {\n data.z = 2;\n mapping(uint8 => s2) storage map = data.recursive;\n s2 storage inner = map[0];\n inner.z = 3;\n inner.recursive[0].z = inner.recursive[1].z + 1;\n }\n}\n// ----\n// check() -> false\n// set() ->\n// check() -> true\n" + }, + "struct_named_constructor.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n bool x;\n }\n S public s;\n\n constructor() {\n s = S({x: true, a: 1});\n }\n}\n// ----\n// s() -> 1, true\n" + }, + "using_for_function_on_struct.sol": { + "content": "library D { struct s { uint a; } function mul(s storage self, uint x) public returns (uint) { return self.a *= x; } }\ncontract C {\n using D for D.s;\n D.s public x;\n function f(uint a) public returns (uint) {\n x.a = 3;\n return x.mul(a);\n }\n}\n// ----\n// library: D\n// f(uint256): 7 -> 0x15\n// x() -> 0x15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_assert/assert.sol b/examples/test/semanticTests/tryCatch_assert/assert.sol new file mode 100644 index 00000000..8b6a7b99 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_assert/assert.sol @@ -0,0 +1,16 @@ +contract C { + function g(bool x) public pure { + assert(x); + } + function f(bool x) public returns (uint) { + // Set the gas to make this work on pre-byzantium VMs + try this.g{gas: 8000}(x) { + return 1; + } catch { + return 2; + } + } +} +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/examples/test/semanticTests/tryCatch_assert/assert_standard_input.json b/examples/test/semanticTests/tryCatch_assert/assert_standard_input.json new file mode 100644 index 00000000..d761ab3d --- /dev/null +++ b/examples/test/semanticTests/tryCatch_assert/assert_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_create/create.sol b/examples/test/semanticTests/tryCatch_create/create.sol new file mode 100644 index 00000000..43d0f22f --- /dev/null +++ b/examples/test/semanticTests/tryCatch_create/create.sol @@ -0,0 +1,32 @@ +contract Reverts { + constructor(uint) { revert("test message."); } +} +contract Succeeds { + constructor(uint) { } +} + +contract C { + function f() public returns (Reverts x, uint, string memory txt) { + uint i = 3; + try new Reverts(i) returns (Reverts r) { + x = r; + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } + function g() public returns (Succeeds x, uint, string memory txt) { + uint i = 8; + try new Succeeds(i) returns (Succeeds r) { + x = r; + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0, 0, 96, 13, "test message." +// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, "success" diff --git a/examples/test/semanticTests/tryCatch_create/create_standard_input.json b/examples/test/semanticTests/tryCatch_create/create_standard_input.json new file mode 100644 index 00000000..12f1af97 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_create/create_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding.sol b/examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding.sol new file mode 100644 index 00000000..2bfc2319 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding.sol @@ -0,0 +1,168 @@ +contract C { + function g(bytes memory revertMsg) public pure returns (uint, uint) { + assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) } + } + function f1() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f1a() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch { + return 2; + } + } + function f1b() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f1c() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch { + return 2; + } + } + function f2() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f2a() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch { + return 2; + } + } + function f2b() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f2c() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch { + return 1; + } + } + function f3() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f3a() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f3b() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f3c() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch { + return 1; + } + } + function f4() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f4a() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch { + return 2; + } + } + function f4b() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f4c() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch { + return 1; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f1() -> 2 +// f1a() -> 2 +// f1b() -> FAILURE, hex"12345678", 0x0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +// f1c() -> 2 +// f2() -> 2 +// f2a() -> 2 +// f2b() -> FAILURE, hex"08c379a0", 0x100, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +// f2c() -> 1 +// f3() -> 2 +// f3a() -> 2 +// f3b() -> FAILURE, hex"08c379a0", 0x20, 48, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +// f3c() -> 1 +// f4() -> 1 +// f4a() -> 1 +// f4b() -> 1 +// f4c() -> 1 diff --git a/examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding_standard_input.json b/examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding_standard_input.json new file mode 100644 index 00000000..848b310a --- /dev/null +++ b/examples/test/semanticTests/tryCatch_invalid_error_encoding/invalid_error_encoding_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_lowLevel/lowLevel.sol b/examples/test/semanticTests/tryCatch_lowLevel/lowLevel.sol new file mode 100644 index 00000000..ac275522 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_lowLevel/lowLevel.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "message"); + return (1, 2); + } + function f(bool b) public returns (uint x, uint y, bytes memory txt) { + try this.g(b) returns (uint a, uint b) { + (x, y) = (a, b); + } catch (bytes memory s) { + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2, 96, 0 +// f(bool): false -> 0, 0, 96, 100, 0x8c379a000000000000000000000000000000000000000000000000000000000, 0x2000000000000000000000000000000000000000000000000000000000, 0x76d657373616765000000000000000000000000000000000000000000, 0 diff --git a/examples/test/semanticTests/tryCatch_lowLevel/lowLevel_standard_input.json b/examples/test/semanticTests/tryCatch_lowLevel/lowLevel_standard_input.json new file mode 100644 index 00000000..04da8b67 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_lowLevel/lowLevel_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + }, + "malformed_panic_4.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n" + }, + "return_function.sol": { + "content": "contract C {\n function g() public returns (uint a, function() external h, uint b) {\n a = 1;\n h = this.fun;\n b = 9;\n }\n function f() public returns (uint, function() external, uint) {\n // Note that the function type uses two stack slots.\n try this.g() returns (uint a, function() external h, uint b) {\n return (a, h, b);\n } catch {\n }\n }\n function fun() public pure {}\n}\n// ----\n// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9\n" + }, + "try_catch_library_call.sol": { + "content": "library L {\n struct S { uint x; }\n function integer(uint t, bool b) public view returns (uint) {\n if (b) {\n return t;\n } else {\n revert(\"failure\");\n }\n }\n function stru(S storage t, bool b) public view returns (uint) {\n if (b) {\n return t.x;\n } else {\n revert(\"failure\");\n }\n }\n}\ncontract C {\n using L for L.S;\n L.S t;\n function f(bool b) public returns (uint, string memory) {\n uint x = 8;\n try L.integer(x, b) returns (uint _x) {\n return (_x, \"\");\n } catch Error(string memory message) {\n return (18, message);\n }\n }\n function g(bool b) public returns (uint, string memory) {\n t.x = 9;\n try t.stru(b) returns (uint x) {\n return (x, \"\");\n } catch Error(string memory message) {\n return (19, message);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// f(bool): true -> 8, 0x40, 0\n// f(bool): false -> 18, 0x40, 7, \"failure\"\n// g(bool): true -> 9, 0x40, 0\n// g(bool): false -> 19, 0x40, 7, \"failure\"\n" + }, + "malformed_panic_2.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n }\n assert(false);\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n }\n assert(false);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "malformed_panic_3.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "lowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, bytes memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch (bytes memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 0\n// f(bool): false -> 0, 0, 96, 100, 0x8c379a000000000000000000000000000000000000000000000000000000000, 0x2000000000000000000000000000000000000000000000000000000000, 0x76d657373616765000000000000000000000000000000000000000000, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_malformed_error/malformed_error.sol b/examples/test/semanticTests/tryCatch_malformed_error/malformed_error.sol new file mode 100644 index 00000000..95c29276 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_error/malformed_error.sol @@ -0,0 +1,88 @@ +contract C { + function f(uint size) public pure { + assembly { + mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) + mstore(4, 0x20) + mstore(0x24, 7) + mstore(0x44, "abcdefg") + revert(0, size) + } + } + function a() public returns (uint) { + try this.f(3) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } catch { + assert(true); + } + } + function b() public returns (uint) { + try this.f(6) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } catch { + assert(true); + } + } + function b2() public returns (uint) { + try this.f(0x43) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } catch { + assert(true); + } + } + function b3() public returns (string memory) { + try this.f(0x4a) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } catch { + assert(true); + } + } + function c() public returns (string memory) { + try this.f(0x4b) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory er) { + assert(true); + return er; + } catch { + assert(false); + } + } + function d() public returns (string memory) { + try this.f(0x100) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory er) { + assert(true); + return er; + } catch { + assert(false); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// a() -> 0x00 +// b() -> 0x00 +// b2() -> 0x00 +// b3() -> 0x20, 0x00 +// c() -> 0x20, 7, "abcdefg" +// d() -> 0x20, 7, "abcdefg" diff --git a/examples/test/semanticTests/tryCatch_malformed_error/malformed_error_standard_input.json b/examples/test/semanticTests/tryCatch_malformed_error/malformed_error_standard_input.json new file mode 100644 index 00000000..5eb55286 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_error/malformed_error_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic.sol b/examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic.sol new file mode 100644 index 00000000..816dab7c --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic.sol @@ -0,0 +1,54 @@ +contract C { + function f(uint size) public pure { + assembly { + mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000) + mstore(4, 0x43) + revert(0, size) + } + } + function a() public returns (uint) { + try this.f(3) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch { + assert(true); + } + } + function b() public returns (uint) { + try this.f(6) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch { + assert(true); + } + } + function c() public returns (uint) { + try this.f(0x24) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } catch { + assert(false); + } + } + function d() public returns (uint) { + try this.f(0x100) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } catch { + assert(false); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// a() -> 0x00 +// b() -> 0x00 +// c() -> 0x43 +// d() -> 0x43 diff --git a/examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic_standard_input.json b/examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic_standard_input.json new file mode 100644 index 00000000..8fafc598 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic/malformed_panic_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2.sol b/examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2.sol new file mode 100644 index 00000000..bf47c01a --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2.sol @@ -0,0 +1,52 @@ +contract C { + function f(uint size) public pure { + assembly { + mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000) + mstore(4, 0x43) + revert(0, size) + } + } + function a() public returns (uint) { + try this.f(3) { + assert(false); + } catch Panic(uint) { + assert(false); + } + // Error will be re-thrown, since there is no low-level catch clause + assert(false); + } + function b() public returns (uint) { + try this.f(6) { + assert(false); + } catch Panic(uint) { + assert(false); + } + // Error will be re-thrown, since there is no low-level catch clause + assert(false); + } + function c() public returns (uint) { + try this.f(0x24) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } + assert(false); + } + function d() public returns (uint) { + try this.f(0x100) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } + assert(false); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// a() -> FAILURE, hex"4e487b" +// b() -> FAILURE, hex"4e487b710000" +// c() -> 0x43 +// d() -> 0x43 diff --git a/examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2_standard_input.json b/examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2_standard_input.json new file mode 100644 index 00000000..24634374 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic_2/malformed_panic_2_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + }, + "malformed_panic_4.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n" + }, + "return_function.sol": { + "content": "contract C {\n function g() public returns (uint a, function() external h, uint b) {\n a = 1;\n h = this.fun;\n b = 9;\n }\n function f() public returns (uint, function() external, uint) {\n // Note that the function type uses two stack slots.\n try this.g() returns (uint a, function() external h, uint b) {\n return (a, h, b);\n } catch {\n }\n }\n function fun() public pure {}\n}\n// ----\n// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9\n" + }, + "try_catch_library_call.sol": { + "content": "library L {\n struct S { uint x; }\n function integer(uint t, bool b) public view returns (uint) {\n if (b) {\n return t;\n } else {\n revert(\"failure\");\n }\n }\n function stru(S storage t, bool b) public view returns (uint) {\n if (b) {\n return t.x;\n } else {\n revert(\"failure\");\n }\n }\n}\ncontract C {\n using L for L.S;\n L.S t;\n function f(bool b) public returns (uint, string memory) {\n uint x = 8;\n try L.integer(x, b) returns (uint _x) {\n return (_x, \"\");\n } catch Error(string memory message) {\n return (18, message);\n }\n }\n function g(bool b) public returns (uint, string memory) {\n t.x = 9;\n try t.stru(b) returns (uint x) {\n return (x, \"\");\n } catch Error(string memory message) {\n return (19, message);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// f(bool): true -> 8, 0x40, 0\n// f(bool): false -> 18, 0x40, 7, \"failure\"\n// g(bool): true -> 9, 0x40, 0\n// g(bool): false -> 19, 0x40, 7, \"failure\"\n" + }, + "malformed_panic_2.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n }\n assert(false);\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n }\n assert(false);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3.sol b/examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3.sol new file mode 100644 index 00000000..cad5aaa4 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3.sol @@ -0,0 +1,58 @@ +contract C { + function f(uint size) public pure { + assembly { + mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000) + mstore(4, 0x43) + revert(0, size) + } + } + function a() public returns (uint) { + try this.f(3) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } + // Error will be re-thrown, since there is no low-level catch clause + assert(false); + } + function b() public returns (uint) { + try this.f(6) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } + // Error will be re-thrown, since there is no low-level catch clause + assert(false); + } + function c() public returns (uint) { + try this.f(0x24) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } catch Error(string memory) { + assert(false); + } + } + function d() public returns (uint) { + try this.f(0x100) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } catch Error(string memory) { + assert(false); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// a() -> FAILURE, hex"4e487b" +// b() -> FAILURE, hex"4e487b710000" +// c() -> 0x43 +// d() -> 0x43 diff --git a/examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3_standard_input.json b/examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3_standard_input.json new file mode 100644 index 00000000..f95a56c1 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic_3/malformed_panic_3_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + }, + "malformed_panic_4.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n" + }, + "return_function.sol": { + "content": "contract C {\n function g() public returns (uint a, function() external h, uint b) {\n a = 1;\n h = this.fun;\n b = 9;\n }\n function f() public returns (uint, function() external, uint) {\n // Note that the function type uses two stack slots.\n try this.g() returns (uint a, function() external h, uint b) {\n return (a, h, b);\n } catch {\n }\n }\n function fun() public pure {}\n}\n// ----\n// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9\n" + }, + "try_catch_library_call.sol": { + "content": "library L {\n struct S { uint x; }\n function integer(uint t, bool b) public view returns (uint) {\n if (b) {\n return t;\n } else {\n revert(\"failure\");\n }\n }\n function stru(S storage t, bool b) public view returns (uint) {\n if (b) {\n return t.x;\n } else {\n revert(\"failure\");\n }\n }\n}\ncontract C {\n using L for L.S;\n L.S t;\n function f(bool b) public returns (uint, string memory) {\n uint x = 8;\n try L.integer(x, b) returns (uint _x) {\n return (_x, \"\");\n } catch Error(string memory message) {\n return (18, message);\n }\n }\n function g(bool b) public returns (uint, string memory) {\n t.x = 9;\n try t.stru(b) returns (uint x) {\n return (x, \"\");\n } catch Error(string memory message) {\n return (19, message);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// f(bool): true -> 8, 0x40, 0\n// f(bool): false -> 18, 0x40, 7, \"failure\"\n// g(bool): true -> 9, 0x40, 0\n// g(bool): false -> 19, 0x40, 7, \"failure\"\n" + }, + "malformed_panic_2.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n }\n assert(false);\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n }\n assert(false);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "malformed_panic_3.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n }\n // Error will be re-thrown, since there is no low-level catch clause\n assert(false);\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> FAILURE, hex\"4e487b\"\n// b() -> FAILURE, hex\"4e487b710000\"\n// c() -> 0x43\n// d() -> 0x43\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4.sol b/examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4.sol new file mode 100644 index 00000000..ad096b9b --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4.sol @@ -0,0 +1,61 @@ +contract C { + function f(uint size) public pure { + assembly { + mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000) + mstore(4, 0x43) + revert(0, size) + } + } + function a() public returns (uint) { + try this.f(3) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } catch { + assert(true); + } + } + function b() public returns (uint) { + try this.f(6) { + assert(false); + } catch Panic(uint) { + assert(false); + } catch Error(string memory) { + assert(false); + } catch { + assert(true); + } + } + function c() public returns (uint) { + try this.f(0x24) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } catch Error(string memory) { + assert(false); + } catch { + assert(false); + } + } + function d() public returns (uint) { + try this.f(0x100) { + assert(false); + } catch Panic(uint c) { + assert(true); + return c; + } catch Error(string memory) { + assert(false); + } catch { + assert(false); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// a() -> 0x00 +// b() -> 0x00 +// c() -> 0x43 diff --git a/examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4_standard_input.json b/examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4_standard_input.json new file mode 100644 index 00000000..d5c7cebc --- /dev/null +++ b/examples/test/semanticTests/tryCatch_malformed_panic_4/malformed_panic_4_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + }, + "malformed_panic_4.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_nested/nested.sol b/examples/test/semanticTests/tryCatch_nested/nested.sol new file mode 100644 index 00000000..7c56a81b --- /dev/null +++ b/examples/test/semanticTests/tryCatch_nested/nested.sol @@ -0,0 +1,33 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "failure"); + return (1, 2); + } + function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) { + try this.g(cond1) returns (uint a, uint b) { + try this.g(cond2) returns (uint a2, uint b2) { + (x, y) = (a, b); + txt = "success"; + } catch Error(string memory s) { + x = 12; + txt = bytes(s); + } catch (bytes memory s) { + x = 13; + txt = s; + } + } catch Error(string memory s) { + x = 99; + txt = bytes(s); + } catch (bytes memory s) { + x = 98; + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool,bool): true, true -> 1, 2, 96, 7, "success" +// f(bool,bool): true, false -> 12, 0, 96, 7, "failure" +// f(bool,bool): false, true -> 99, 0, 96, 7, "failure" +// f(bool,bool): false, false -> 99, 0, 96, 7, "failure" diff --git a/examples/test/semanticTests/tryCatch_nested/nested_standard_input.json b/examples/test/semanticTests/tryCatch_nested/nested_standard_input.json new file mode 100644 index 00000000..a3fb1362 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_nested/nested_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_panic/panic.sol b/examples/test/semanticTests/tryCatch_panic/panic.sol new file mode 100644 index 00000000..eb7dd8c8 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_panic/panic.sol @@ -0,0 +1,33 @@ +contract C { + function uf(bool b, uint x, uint y) public pure returns (uint) { + require(b, "failure"); + return x - y; + } + function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) { + try this.uf(b, x, y) returns (uint b) { + r = b; + } catch Panic(uint c) { + code = c; + } + } + function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) { + try this.uf(b, x, y) returns (uint b) { + r = b; + } catch Panic(uint c) { + code = c; + } catch Error(string memory _errmsg) { + msg_ = _errmsg; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00 +// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11 +// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex"08c379a0", 0x20, 7, "failure" +// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex"08c379a0", 0x20, 7, "failure" +// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00 +// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00 +// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, "failure" +// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, "failure" diff --git a/examples/test/semanticTests/tryCatch_panic/panic_standard_input.json b/examples/test/semanticTests/tryCatch_panic/panic_standard_input.json new file mode 100644 index 00000000..6a25c6ee --- /dev/null +++ b/examples/test/semanticTests/tryCatch_panic/panic_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_return_function/return_function.sol b/examples/test/semanticTests/tryCatch_return_function/return_function.sol new file mode 100644 index 00000000..6aac30fe --- /dev/null +++ b/examples/test/semanticTests/tryCatch_return_function/return_function.sol @@ -0,0 +1,17 @@ +contract C { + function g() public returns (uint a, function() external h, uint b) { + a = 1; + h = this.fun; + b = 9; + } + function f() public returns (uint, function() external, uint) { + // Note that the function type uses two stack slots. + try this.g() returns (uint a, function() external h, uint b) { + return (a, h, b); + } catch { + } + } + function fun() public pure {} +} +// ---- +// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9 diff --git a/examples/test/semanticTests/tryCatch_return_function/return_function_standard_input.json b/examples/test/semanticTests/tryCatch_return_function/return_function_standard_input.json new file mode 100644 index 00000000..c0a0a9fa --- /dev/null +++ b/examples/test/semanticTests/tryCatch_return_function/return_function_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + }, + "malformed_panic_4.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n" + }, + "return_function.sol": { + "content": "contract C {\n function g() public returns (uint a, function() external h, uint b) {\n a = 1;\n h = this.fun;\n b = 9;\n }\n function f() public returns (uint, function() external, uint) {\n // Note that the function type uses two stack slots.\n try this.g() returns (uint a, function() external h, uint b) {\n return (a, h, b);\n } catch {\n }\n }\n function fun() public pure {}\n}\n// ----\n// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_simple/simple.sol b/examples/test/semanticTests/tryCatch_simple/simple.sol new file mode 100644 index 00000000..48bccfa5 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_simple/simple.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool b) public pure returns (uint x, uint y) { + require(b); + return (1, 2); + } + function f(bool flag) public view returns (uint x, uint y) { + try this.g(flag) returns (uint a, uint b) { + (x, y) = (a, b); + } catch { + (x, y) = (9, 10); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2 +// f(bool): false -> 9, 10 diff --git a/examples/test/semanticTests/tryCatch_simple/simple_standard_input.json b/examples/test/semanticTests/tryCatch_simple/simple_standard_input.json new file mode 100644 index 00000000..852ce186 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_simple/simple_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple.sol b/examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple.sol new file mode 100644 index 00000000..6368edf7 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool b) public pure returns (uint x) { + require(b); + return 13; + } + function f(bool flag) public view returns (uint x) { + try this.g(flag) returns (uint a) { + x = a; + } catch { + x = 9; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 13 +// f(bool): false -> 9 diff --git a/examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple_standard_input.json b/examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple_standard_input.json new file mode 100644 index 00000000..018ba83d --- /dev/null +++ b/examples/test/semanticTests/tryCatch_simple_notuple/simple_notuple_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_structured/structured.sol b/examples/test/semanticTests/tryCatch_structured/structured.sol new file mode 100644 index 00000000..e5aa238b --- /dev/null +++ b/examples/test/semanticTests/tryCatch_structured/structured.sol @@ -0,0 +1,19 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "message"); + return (1, 2); + } + function f(bool b) public returns (uint x, uint y, string memory txt) { + try this.g(b) returns (uint a, uint b) { + (x, y) = (a, b); + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2, 0x60, 7, "success" +// f(bool): false -> 0, 0, 0x60, 7, "message" diff --git a/examples/test/semanticTests/tryCatch_structured/structured_standard_input.json b/examples/test/semanticTests/tryCatch_structured/structured_standard_input.json new file mode 100644 index 00000000..b5a03ac5 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_structured/structured_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel.sol b/examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel.sol new file mode 100644 index 00000000..8a8cb3d1 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel.sol @@ -0,0 +1,23 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes"); + return (1, 2); + } + function f(bool cond) public returns (uint x, uint y, bytes memory txt) { + try this.g(cond) returns (uint a, uint b) { + (x, y) = (a, b); + txt = "success"; + } catch Error(string memory s) { + x = 99; + txt = bytes(s); + } catch (bytes memory s) { + x = 98; + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2, 96, 7, "success" +// f(bool): false -> 99, 0, 96, 82, "message longer than 32 bytes 32 ", "bytes 32 bytes 32 bytes 32 bytes", " 32 bytes 32 bytes" diff --git a/examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel_standard_input.json b/examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel_standard_input.json new file mode 100644 index 00000000..1d780f56 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_structuredAndLowLevel/structuredAndLowLevel_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_super_trivial/super_trivial.sol b/examples/test/semanticTests/tryCatch_super_trivial/super_trivial.sol new file mode 100644 index 00000000..98fbcddb --- /dev/null +++ b/examples/test/semanticTests/tryCatch_super_trivial/super_trivial.sol @@ -0,0 +1,17 @@ +contract C { + function g(bool x) external pure { + require(x); + } + function f(bool x) public returns (uint) { + try this.g(x) { + return 1; + } catch { + return 2; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/examples/test/semanticTests/tryCatch_super_trivial/super_trivial_standard_input.json b/examples/test/semanticTests/tryCatch_super_trivial/super_trivial_standard_input.json new file mode 100644 index 00000000..a9fcb799 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_super_trivial/super_trivial_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_trivial/trivial.sol b/examples/test/semanticTests/tryCatch_trivial/trivial.sol new file mode 100644 index 00000000..d43477e9 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_trivial/trivial.sol @@ -0,0 +1,16 @@ +contract C { + function g(bool x) public pure { + require(x); + } + function f(bool x) public returns (uint) { + // Set the gas to make this work on pre-byzantium VMs + try this.g{gas: 8000}(x) { + return 1; + } catch { + return 2; + } + } +} +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/examples/test/semanticTests/tryCatch_trivial/trivial_standard_input.json b/examples/test/semanticTests/tryCatch_trivial/trivial_standard_input.json new file mode 100644 index 00000000..03bb1659 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_trivial/trivial_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call.sol b/examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call.sol new file mode 100644 index 00000000..e7bad76b --- /dev/null +++ b/examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call.sol @@ -0,0 +1,45 @@ +library L { + struct S { uint x; } + function integer(uint t, bool b) public view returns (uint) { + if (b) { + return t; + } else { + revert("failure"); + } + } + function stru(S storage t, bool b) public view returns (uint) { + if (b) { + return t.x; + } else { + revert("failure"); + } + } +} +contract C { + using L for L.S; + L.S t; + function f(bool b) public returns (uint, string memory) { + uint x = 8; + try L.integer(x, b) returns (uint _x) { + return (_x, ""); + } catch Error(string memory message) { + return (18, message); + } + } + function g(bool b) public returns (uint, string memory) { + t.x = 9; + try t.stru(b) returns (uint x) { + return (x, ""); + } catch Error(string memory message) { + return (19, message); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// library: L +// f(bool): true -> 8, 0x40, 0 +// f(bool): false -> 18, 0x40, 7, "failure" +// g(bool): true -> 9, 0x40, 0 +// g(bool): false -> 19, 0x40, 7, "failure" diff --git a/examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call_standard_input.json b/examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call_standard_input.json new file mode 100644 index 00000000..e835d4f9 --- /dev/null +++ b/examples/test/semanticTests/tryCatch_try_catch_library_call/try_catch_library_call_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "nested.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"failure\");\n return (1, 2);\n }\n function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond1) returns (uint a, uint b) {\n try this.g(cond2) returns (uint a2, uint b2) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 12;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 13;\n txt = s;\n }\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool,bool): true, true -> 1, 2, 96, 7, \"success\"\n// f(bool,bool): true, false -> 12, 0, 96, 7, \"failure\"\n// f(bool,bool): false, true -> 99, 0, 96, 7, \"failure\"\n// f(bool,bool): false, false -> 99, 0, 96, 7, \"failure\"\n" + }, + "trivial.sol": { + "content": "contract C {\n function g(bool x) public pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "create.sol": { + "content": "contract Reverts {\n constructor(uint) { revert(\"test message.\"); }\n}\ncontract Succeeds {\n constructor(uint) { }\n}\n\ncontract C {\n function f() public returns (Reverts x, uint, string memory txt) {\n uint i = 3;\n try new Reverts(i) returns (Reverts r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n function g() public returns (Succeeds x, uint, string memory txt) {\n uint i = 8;\n try new Succeeds(i) returns (Succeeds r) {\n x = r;\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0, 0, 96, 13, \"test message.\"\n// g() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0, 96, 7, \"success\"\n" + }, + "simple_notuple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x) {\n require(b);\n return 13;\n }\n function f(bool flag) public view returns (uint x) {\n try this.g(flag) returns (uint a) {\n x = a;\n } catch {\n x = 9;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 13\n// f(bool): false -> 9\n" + }, + "malformed_error.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x20)\n mstore(0x24, 7)\n mstore(0x44, \"abcdefg\")\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b2() public returns (uint) {\n try this.f(0x43) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b3() public returns (string memory) {\n try this.f(0x4a) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (string memory) {\n try this.f(0x4b) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n function d() public returns (string memory) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory er) {\n assert(true);\n return er;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// b2() -> 0x00\n// b3() -> 0x20, 0x00\n// c() -> 0x20, 7, \"abcdefg\"\n// d() -> 0x20, 7, \"abcdefg\"\n" + }, + "panic.sol": { + "content": "contract C {\n function uf(bool b, uint x, uint y) public pure returns (uint) {\n require(b, \"failure\");\n return x - y;\n }\n function onlyPanic(bool b, uint x, uint y) public returns (uint r, uint code) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n }\n }\n function panicAndError(bool b, uint x, uint y) public returns (uint r, uint code, string memory msg_) {\n try this.uf(b, x, y) returns (uint b) {\n r = b;\n } catch Panic(uint c) {\n code = c;\n } catch Error(string memory _errmsg) {\n msg_ = _errmsg;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// onlyPanic(bool,uint256,uint256): true, 7, 6 -> 1, 0x00\n// onlyPanic(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11\n// onlyPanic(bool,uint256,uint256): false, 7, 6 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// onlyPanic(bool,uint256,uint256): false, 6, 7 -> FAILURE, hex\"08c379a0\", 0x20, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): true, 7, 6 -> 1, 0x00, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): true, 6, 7 -> 0x00, 0x11, 0x60, 0x00\n// panicAndError(bool,uint256,uint256): false, 7, 6 -> 0x00, 0x00, 0x60, 7, \"failure\"\n// panicAndError(bool,uint256,uint256): false, 6, 7 -> 0x00, 0x00, 0x60, 7, \"failure\"\n" + }, + "super_trivial.sol": { + "content": "contract C {\n function g(bool x) external pure {\n require(x);\n }\n function f(bool x) public returns (uint) {\n try this.g(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "assert.sol": { + "content": "contract C {\n function g(bool x) public pure {\n assert(x);\n }\n function f(bool x) public returns (uint) {\n // Set the gas to make this work on pre-byzantium VMs\n try this.g{gas: 8000}(x) {\n return 1;\n } catch {\n return 2;\n }\n }\n}\n// ----\n// f(bool): true -> 1\n// f(bool): false -> 2\n" + }, + "structuredAndLowLevel.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes\");\n return (1, 2);\n }\n function f(bool cond) public returns (uint x, uint y, bytes memory txt) {\n try this.g(cond) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n x = 99;\n txt = bytes(s);\n } catch (bytes memory s) {\n x = 98;\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 96, 7, \"success\"\n// f(bool): false -> 99, 0, 96, 82, \"message longer than 32 bytes 32 \", \"bytes 32 bytes 32 bytes 32 bytes\", \" 32 bytes 32 bytes\"\n" + }, + "malformed_panic.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n// d() -> 0x43\n" + }, + "structured.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint, uint) {\n require(b, \"message\");\n return (1, 2);\n }\n function f(bool b) public returns (uint x, uint y, string memory txt) {\n try this.g(b) returns (uint a, uint b) {\n (x, y) = (a, b);\n txt = \"success\";\n } catch Error(string memory s) {\n txt = s;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2, 0x60, 7, \"success\"\n// f(bool): false -> 0, 0, 0x60, 7, \"message\"\n" + }, + "simple.sol": { + "content": "contract C {\n function g(bool b) public pure returns (uint x, uint y) {\n require(b);\n return (1, 2);\n }\n function f(bool flag) public view returns (uint x, uint y) {\n try this.g(flag) returns (uint a, uint b) {\n (x, y) = (a, b);\n } catch {\n (x, y) = (9, 10);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 9, 10\n" + }, + "invalid_error_encoding.sol": { + "content": "contract C {\n function g(bytes memory revertMsg) public pure returns (uint, uint) {\n assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) }\n }\n function f1() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f1a() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f1b() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f1c() public returns (uint x) {\n // Invalid signature\n try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 2;\n }\n }\n function f2() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f2a() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f2b() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f2c() public returns (uint x) {\n // Valid signature but illegal offset\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f3() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3a() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f3b() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f3c() public returns (uint x) {\n // Valid up to length\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n function f4() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch (bytes memory) {\n return 2;\n }\n }\n function f4a() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n } catch {\n return 2;\n }\n }\n function f4b() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch Error(string memory) {\n return 1;\n }\n }\n function f4c() public returns (uint x) {\n // Fully valid\n try this.g(abi.encodeWithSignature(\"Error(string)\", uint(0x20), uint(0x7), bytes7(\"abcdefg\"))) returns (uint a, uint b) {\n return 0;\n } catch {\n return 1;\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f1() -> 2\n// f1a() -> 2\n// f1b() -> FAILURE, hex\"12345678\", 0x0, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f1c() -> 2\n// f2() -> 2\n// f2a() -> 2\n// f2b() -> FAILURE, hex\"08c379a0\", 0x100, 0, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f2c() -> 1\n// f3() -> 2\n// f3a() -> 2\n// f3b() -> FAILURE, hex\"08c379a0\", 0x20, 48, \"\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\"\n// f3c() -> 1\n// f4() -> 1\n// f4a() -> 1\n// f4b() -> 1\n// f4c() -> 1\n" + }, + "malformed_panic_4.sol": { + "content": "contract C {\n function f(uint size) public pure {\n assembly {\n mstore(0, 0x4e487b7100000000000000000000000000000000000000000000000000000000)\n mstore(4, 0x43)\n revert(0, size)\n }\n }\n function a() public returns (uint) {\n try this.f(3) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function b() public returns (uint) {\n try this.f(6) {\n assert(false);\n } catch Panic(uint) {\n assert(false);\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(true);\n }\n }\n function c() public returns (uint) {\n try this.f(0x24) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n function d() public returns (uint) {\n try this.f(0x100) {\n assert(false);\n } catch Panic(uint c) {\n assert(true);\n return c;\n } catch Error(string memory) {\n assert(false);\n } catch {\n assert(false);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// a() -> 0x00\n// b() -> 0x00\n// c() -> 0x43\n" + }, + "return_function.sol": { + "content": "contract C {\n function g() public returns (uint a, function() external h, uint b) {\n a = 1;\n h = this.fun;\n b = 9;\n }\n function f() public returns (uint, function() external, uint) {\n // Note that the function type uses two stack slots.\n try this.g() returns (uint a, function() external h, uint b) {\n return (a, h, b);\n } catch {\n }\n }\n function fun() public pure {}\n}\n// ----\n// f() -> 0x1, 0xc06afe3a8444fc0004668591e8306bfb9968e79e946644cd0000000000000000, 9\n" + }, + "try_catch_library_call.sol": { + "content": "library L {\n struct S { uint x; }\n function integer(uint t, bool b) public view returns (uint) {\n if (b) {\n return t;\n } else {\n revert(\"failure\");\n }\n }\n function stru(S storage t, bool b) public view returns (uint) {\n if (b) {\n return t.x;\n } else {\n revert(\"failure\");\n }\n }\n}\ncontract C {\n using L for L.S;\n L.S t;\n function f(bool b) public returns (uint, string memory) {\n uint x = 8;\n try L.integer(x, b) returns (uint _x) {\n return (_x, \"\");\n } catch Error(string memory message) {\n return (18, message);\n }\n }\n function g(bool b) public returns (uint, string memory) {\n t.x = 9;\n try t.stru(b) returns (uint x) {\n return (x, \"\");\n } catch Error(string memory message) {\n return (19, message);\n }\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// f(bool): true -> 8, 0x40, 0\n// f(bool): false -> 18, 0x40, 7, \"failure\"\n// g(bool): true -> 9, 0x40, 0\n// g(bool): false -> 19, 0x40, 7, \"failure\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param.sol b/examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param.sol new file mode 100644 index 00000000..6a41ddbe --- /dev/null +++ b/examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param.sol @@ -0,0 +1,17 @@ +abstract contract A { + constructor (mapping (uint => uint) [] storage m) { + m.push(); + m[0][1] = 2; + } +} + +contract C is A { + mapping(uint => mapping (uint => uint) []) public m; + + constructor() A(m[1]) { + } +} +// ---- +// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE +// m(uint256,uint256,uint256): 1, 0, 1 -> 2 +// m(uint256,uint256,uint256): 1, 0, 5 -> 0 diff --git a/examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param_standard_input.json b/examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param_standard_input.json new file mode 100644 index 00000000..f6a0e318 --- /dev/null +++ b/examples/test/semanticTests/types_array_mapping_abstract_constructor_param/array_mapping_abstract_constructor_param_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type.sol b/examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type.sol new file mode 100644 index 00000000..8350628e --- /dev/null +++ b/examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type.sol @@ -0,0 +1,9 @@ +contract C { + function f(uint256 x) public pure returns (uint256, uint256) { + uint256 b = x; + x = 42; + return (x, b); + } +} +// ---- +// f(uint256): 23 -> 42, 23 diff --git a/examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type_standard_input.json b/examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type_standard_input.json new file mode 100644 index 00000000..fe2268ed --- /dev/null +++ b/examples/test/semanticTests/types_assign_calldata_value_type/assign_calldata_value_type_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size.sol new file mode 100644 index 00000000..fdfafa9e --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToBytes(bytes2 input) public returns (bytes4 ret) { + return bytes4(input); + } +} +// ---- +// bytesToBytes(bytes2): "ab" -> "ab" diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size_standard_input.json new file mode 100644 index 00000000..9db91207 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_greater_size/convert_fixed_bytes_to_fixed_bytes_greater_size_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size.sol new file mode 100644 index 00000000..5c9a6cdc --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToBytes(bytes4 input) public returns (bytes4 ret) { + return bytes4(input); + } +} +// ---- +// bytesToBytes(bytes4): "abcd" -> "abcd" diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size_standard_input.json new file mode 100644 index 00000000..d60e3c0f --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_same_size/convert_fixed_bytes_to_fixed_bytes_same_size_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + }, + "mapping_contract_key.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return table[k];\n }\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "tuple_assign_multi_slot_grow.sol": { + "content": "contract C {\n\n\tfunction f() public pure returns (uint, uint, uint) {\n\t\tbytes memory a; bytes memory b; bytes memory c;\n\t\t(a, (b, c)) = (\"0\", (\"1\", \"2\"));\n\t\treturn (uint8(a[0]), uint8(b[0]), uint8(c[0]));\n\t}\n\n}\n// ----\n// f() -> 0x30, 0x31, 0x32\n" + }, + "convert_fixed_bytes_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"abcd\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size.sol new file mode 100644 index 00000000..2052c9da --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToBytes(bytes4 input) public returns (bytes2 ret) { + return bytes2(input); + } +} +// ---- +// bytesToBytes(bytes4): "abcd" -> "ab" diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size_standard_input.json new file mode 100644 index 00000000..8837cf4c --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_fixed_bytes_smaller_size/convert_fixed_bytes_to_fixed_bytes_smaller_size_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + }, + "mapping_contract_key.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return table[k];\n }\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "tuple_assign_multi_slot_grow.sol": { + "content": "contract C {\n\n\tfunction f() public pure returns (uint, uint, uint) {\n\t\tbytes memory a; bytes memory b; bytes memory c;\n\t\t(a, (b, c)) = (\"0\", (\"1\", \"2\"));\n\t\treturn (uint8(a[0]), uint8(b[0]), uint8(c[0]));\n\t}\n\n}\n// ----\n// f() -> 0x30, 0x31, 0x32\n" + }, + "convert_fixed_bytes_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"abcd\"\n" + }, + "convert_fixed_bytes_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes2 ret) {\n return bytes2(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size.sol new file mode 100644 index 00000000..b0ab07f5 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToUint(bytes4 s) public returns (uint64 h) { + return uint64(uint32(s)); + } +} +// ---- +// bytesToUint(bytes4): "abcd" -> 0x61626364 diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size_standard_input.json new file mode 100644 index 00000000..61d3f589 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_greater_size/convert_fixed_bytes_to_uint_greater_size_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size.sol new file mode 100644 index 00000000..ff1dfebf --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToUint(bytes1 s) public returns (uint8 h) { + return uint8(s); + } +} +// ---- +// bytesToUint(bytes1): "a" -> 0x61 diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size_standard_input.json new file mode 100644 index 00000000..7550f99c --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_min_size/convert_fixed_bytes_to_uint_same_min_size_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type.sol new file mode 100644 index 00000000..390bf4b0 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToUint(bytes32 s) public returns (uint256 h) { + return uint(s); + } +} +// ---- +// bytesToUint(bytes32): "abc2" -> left(0x61626332) diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type_standard_input.json new file mode 100644 index 00000000..12851b50 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_same_type/convert_fixed_bytes_to_uint_same_type_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size.sol b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size.sol new file mode 100644 index 00000000..eb450993 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size.sol @@ -0,0 +1,7 @@ +contract Test { + function bytesToUint(bytes4 s) public returns (uint16 h) { + return uint16(uint32(s)); + } +} +// ---- +// bytesToUint(bytes4): "abcd" -> 0x6364 diff --git a/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size_standard_input.json b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size_standard_input.json new file mode 100644 index 00000000..3bc644a2 --- /dev/null +++ b/examples/test/semanticTests/types_convert_fixed_bytes_to_uint_smaller_size/convert_fixed_bytes_to_uint_smaller_size_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size.sol b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size.sol new file mode 100644 index 00000000..9949b477 --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size.sol @@ -0,0 +1,7 @@ +contract Test { + function UintToBytes(uint16 h) public returns (bytes8 s) { + return bytes8(uint64(h)); + } +} +// ---- +// UintToBytes(uint16): 0x6162 -> "\x00\x00\x00\x00\x00\x00ab" diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size_standard_input.json b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size_standard_input.json new file mode 100644 index 00000000..a150993c --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_greater_size/convert_uint_to_fixed_bytes_greater_size_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size.sol b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size.sol new file mode 100644 index 00000000..60b9a4cf --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size.sol @@ -0,0 +1,7 @@ +contract Test { + function UintToBytes(uint8 h) public returns (bytes1 s) { + return bytes1(h); + } +} +// ---- +// UintToBytes(uint8): 0x61 -> "a" diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size_standard_input.json b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size_standard_input.json new file mode 100644 index 00000000..78674354 --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_min_size/convert_uint_to_fixed_bytes_same_min_size_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size.sol b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size.sol new file mode 100644 index 00000000..5662d909 --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size.sol @@ -0,0 +1,7 @@ +contract Test { + function uintToBytes(uint256 h) public returns (bytes32 s) { + return bytes32(h); + } +} +// ---- +// uintToBytes(uint256): left(0x616263) -> left(0x616263) diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size_standard_input.json b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size_standard_input.json new file mode 100644 index 00000000..67973dc5 --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_same_size/convert_uint_to_fixed_bytes_same_size_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size.sol b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size.sol new file mode 100644 index 00000000..963cbc34 --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size.sol @@ -0,0 +1,7 @@ +contract Test { + function uintToBytes(uint32 h) public returns (bytes2 s) { + return bytes2(uint16(h)); + } +} +// ---- +// uintToBytes(uint32): 0x61626364 -> "cd" diff --git a/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size_standard_input.json b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size_standard_input.json new file mode 100644 index 00000000..b7cb4b01 --- /dev/null +++ b/examples/test/semanticTests/types_convert_uint_to_fixed_bytes_smaller_size/convert_uint_to_fixed_bytes_smaller_size_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_external_function_to_address/external_function_to_address.sol b/examples/test/semanticTests/types_external_function_to_address/external_function_to_address.sol new file mode 100644 index 00000000..fb938d37 --- /dev/null +++ b/examples/test/semanticTests/types_external_function_to_address/external_function_to_address.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (bool) { + return this.f.address == address(this); + } + function g(function() external cb) public returns (address) { + return cb.address; + } +} +// ---- +// f() -> true +// g(function): hex"00000000000000000000000000000000000004226121ff00000000000000000" -> 0x42 diff --git a/examples/test/semanticTests/types_external_function_to_address/external_function_to_address_standard_input.json b/examples/test/semanticTests/types_external_function_to_address/external_function_to_address_standard_input.json new file mode 100644 index 00000000..37460dcc --- /dev/null +++ b/examples/test/semanticTests/types_external_function_to_address/external_function_to_address_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param.sol b/examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param.sol new file mode 100644 index 00000000..e9ff60d5 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param.sol @@ -0,0 +1,15 @@ +abstract contract A { + constructor (mapping (uint => uint) storage m) { + m[5] = 20; + } +} + +contract C is A { + mapping (uint => uint) public m; + + constructor() A(m) { + } +} +// ---- +// m(uint256): 1 -> 0 +// m(uint256): 5 -> 20 diff --git a/examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param_standard_input.json b/examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param_standard_input.json new file mode 100644 index 00000000..ec2ecfb5 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_abstract_constructor_param/mapping_abstract_constructor_param_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key.sol b/examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key.sol new file mode 100644 index 00000000..401776ff --- /dev/null +++ b/examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key.sol @@ -0,0 +1,26 @@ +interface A {} +contract test { + mapping(A => uint8) table; + function get(A k) public returns (uint8 v) { + return table[k]; + } + function set(A k, uint8 v) public { + table[k] = v; + } +} +// ---- +// get(address): 0 -> 0 +// get(address): 0x01 -> 0 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x01, 0xa1 -> +// get(address): 0 -> 0 +// get(address): 0x01 -> 0xa1 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x00, 0xef -> +// get(address): 0 -> 0xef +// get(address): 0x01 -> 0xa1 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x01, 0x05 -> +// get(address): 0 -> 0xef +// get(address): 0x01 -> 0x05 +// get(address): 0xa7 -> 0 diff --git a/examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key_standard_input.json b/examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key_standard_input.json new file mode 100644 index 00000000..ebe7fc99 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_contract_key/mapping_contract_key_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + }, + "mapping_contract_key.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return table[k];\n }\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter.sol b/examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter.sol new file mode 100644 index 00000000..ee916a63 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter.sol @@ -0,0 +1,38 @@ +interface A {} +contract test { + mapping(A => uint8) public table; + function set(A k, uint8 v) public { + table[k] = v; + } + function get(A k) public returns (uint8) { + return this.table(k); + } +} +// ---- +// table(address): 0 -> 0 +// table(address): 0x01 -> 0 +// table(address): 0xa7 -> 0 +// get(address): 0 -> 0 +// get(address): 0x01 -> 0 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x01, 0xa1 -> +// table(address): 0 -> 0 +// table(address): 0x01 -> 0xa1 +// table(address): 0xa7 -> 0 +// get(address): 0 -> 0 +// get(address): 0x01 -> 0xa1 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x00, 0xef -> +// table(address): 0 -> 0xef +// table(address): 0x01 -> 0xa1 +// table(address): 0xa7 -> 0 +// get(address): 0 -> 0xef +// get(address): 0x01 -> 0xa1 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x01, 0x05 -> +// table(address): 0 -> 0xef +// table(address): 0x01 -> 0x05 +// table(address): 0xa7 -> 0 +// get(address): 0 -> 0xef +// get(address): 0x01 -> 0x05 +// get(address): 0xa7 -> 0 diff --git a/examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter_standard_input.json b/examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter_standard_input.json new file mode 100644 index 00000000..ae35c8f3 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_contract_key_getter/mapping_contract_key_getter_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library.sol b/examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library.sol new file mode 100644 index 00000000..bedb605c --- /dev/null +++ b/examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library.sol @@ -0,0 +1,35 @@ +interface A {} +library L { + function get(mapping(A => uint8) storage table, A k) external returns (uint8) { + return table[k]; + } + function set(mapping(A => uint8) storage table, A k, uint8 v) external { + table[k] = v; + } +} +contract test { + mapping(A => uint8) table; + function get(A k) public returns (uint8 v) { + return L.get(table, k); + } + function set(A k, uint8 v) public { + L.set(table, k, v); + } +} +// ---- +// library: L +// get(address): 0 -> 0 +// get(address): 0x01 -> 0 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x01, 0xa1 -> +// get(address): 0 -> 0 +// get(address): 0x01 -> 0xa1 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x00, 0xef -> +// get(address): 0 -> 0xef +// get(address): 0x01 -> 0xa1 +// get(address): 0xa7 -> 0 +// set(address,uint8): 0x01, 0x05 -> +// get(address): 0 -> 0xef +// get(address): 0x01 -> 0x05 +// get(address): 0xa7 -> 0 diff --git a/examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library_standard_input.json b/examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library_standard_input.json new file mode 100644 index 00000000..7902993b --- /dev/null +++ b/examples/test/semanticTests/types_mapping_contract_key_library/mapping_contract_key_library_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping.sol b/examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping.sol new file mode 100644 index 00000000..26e8294e --- /dev/null +++ b/examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping.sol @@ -0,0 +1,34 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8[3] x; + uint8[][] y; + uint16 z; + } + + mapping (uint8 => S) src; + mapping (uint8 => S) dst; + + constructor() { + uint8[] memory d = new uint8[](2); + d[0] = 3; + d[1] = 4; + + uint8[][] memory y = new uint8[][](2); + y[0] = d; + y[1] = d; + + src[0] = S({x: [7, 8, 9], y: y, z: 13}); + } + + function f() public returns (S memory) { + dst[0] = src[0]; + return dst[0]; + } +} +// ---- +// f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4 +// gas irOptimized: 197102 +// gas legacy: 199887 +// gas legacyOptimized: 196845 diff --git a/examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping_standard_input.json b/examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping_standard_input.json new file mode 100644 index 00000000..9799878e --- /dev/null +++ b/examples/test/semanticTests/types_mapping_copy_from_mapping_to_mapping/copy_from_mapping_to_mapping_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "copy_struct_to_array_stored_in_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n }\n\n constructor() {\n s = S({x: 7});\n m2[0].push();\n }\n\n S s;\n\n mapping (uint8 => S[2]) m1;\n mapping (uint8 => S[]) m2;\n\n function from_storage_to_static_array() public returns (S[2] memory) {\n m1[0][1] = s;\n return m1[0];\n }\n\n function from_storage_to_dynamic_array() public returns (S[] memory) {\n m2[0][0] = s;\n return m2[0];\n }\n\n function from_memory_to_static_array() public returns (S[2] memory) {\n S memory sLocal = s;\n m1[0][1] = sLocal;\n return m1[0];\n }\n\n function from_memory_to_dynamic_array() public returns (S[] memory) {\n S memory sLocal = s;\n m2[0][0] = sLocal;\n return m2[0];\n }\n\n function from_calldata_to_static_array(S calldata sCalldata) public returns (S[2] memory) {\n m1[0][1] = sCalldata;\n return m1[0];\n }\n\n function from_calldata_to_dynamic_array(S calldata sCalldata) public returns (S[] memory) {\n m2[0][0] = sCalldata;\n return m2[0];\n }\n}\n// ----\n// from_storage_to_static_array() -> 0, 7\n// from_storage_to_dynamic_array() -> 0x20, 1, 7\n// from_memory_to_static_array() -> 0, 7\n// from_memory_to_dynamic_array() -> 0x20, 1, 7\n// from_calldata_to_static_array((uint8)): 8 -> 0, 8\n// from_calldata_to_dynamic_array((uint8)): 8 -> 0x20, 1, 8\n" + }, + "copy_from_mapping_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[3] x;\n uint8[][] y;\n uint16 z;\n }\n\n mapping (uint8 => S) src;\n mapping (uint8 => S) dst;\n\n constructor() {\n uint8[] memory d = new uint8[](2);\n d[0] = 3;\n d[1] = 4;\n\n uint8[][] memory y = new uint8[][](2);\n y[0] = d;\n y[1] = d;\n\n src[0] = S({x: [7, 8, 9], y: y, z: 13});\n }\n\n function f() public returns (S memory) {\n dst[0] = src[0];\n return dst[0];\n }\n}\n// ----\n// f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4\n// gas irOptimized: 197102\n// gas legacy: 199887\n// gas legacyOptimized: 196845\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping.sol b/examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping.sol new file mode 100644 index 00000000..43f2a80f --- /dev/null +++ b/examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping.sol @@ -0,0 +1,56 @@ +pragma abicoder v2; + +contract C { + struct S { + uint8 x; + } + + constructor() { + s = S({x: 7}); + m2[0].push(); + } + + S s; + + mapping (uint8 => S[2]) m1; + mapping (uint8 => S[]) m2; + + function from_storage_to_static_array() public returns (S[2] memory) { + m1[0][1] = s; + return m1[0]; + } + + function from_storage_to_dynamic_array() public returns (S[] memory) { + m2[0][0] = s; + return m2[0]; + } + + function from_memory_to_static_array() public returns (S[2] memory) { + S memory sLocal = s; + m1[0][1] = sLocal; + return m1[0]; + } + + function from_memory_to_dynamic_array() public returns (S[] memory) { + S memory sLocal = s; + m2[0][0] = sLocal; + return m2[0]; + } + + function from_calldata_to_static_array(S calldata sCalldata) public returns (S[2] memory) { + m1[0][1] = sCalldata; + return m1[0]; + } + + function from_calldata_to_dynamic_array(S calldata sCalldata) public returns (S[] memory) { + m2[0][0] = sCalldata; + return m2[0]; + } +} +// ---- +// from_storage_to_static_array() -> 0, 7 +// from_storage_to_dynamic_array() -> 0x20, 1, 7 +// from_memory_to_static_array() -> 0, 7 +// from_memory_to_dynamic_array() -> 0x20, 1, 7 +// from_calldata_to_static_array((uint8)): 8 -> 0, 8 +// from_calldata_to_dynamic_array((uint8)): 8 -> 0x20, 1, 8 diff --git a/examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping_standard_input.json b/examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping_standard_input.json new file mode 100644 index 00000000..01738a08 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_copy_struct_to_array_stored_in_mapping/copy_struct_to_array_stored_in_mapping_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "copy_struct_to_array_stored_in_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n }\n\n constructor() {\n s = S({x: 7});\n m2[0].push();\n }\n\n S s;\n\n mapping (uint8 => S[2]) m1;\n mapping (uint8 => S[]) m2;\n\n function from_storage_to_static_array() public returns (S[2] memory) {\n m1[0][1] = s;\n return m1[0];\n }\n\n function from_storage_to_dynamic_array() public returns (S[] memory) {\n m2[0][0] = s;\n return m2[0];\n }\n\n function from_memory_to_static_array() public returns (S[2] memory) {\n S memory sLocal = s;\n m1[0][1] = sLocal;\n return m1[0];\n }\n\n function from_memory_to_dynamic_array() public returns (S[] memory) {\n S memory sLocal = s;\n m2[0][0] = sLocal;\n return m2[0];\n }\n\n function from_calldata_to_static_array(S calldata sCalldata) public returns (S[2] memory) {\n m1[0][1] = sCalldata;\n return m1[0];\n }\n\n function from_calldata_to_dynamic_array(S calldata sCalldata) public returns (S[] memory) {\n m2[0][0] = sCalldata;\n return m2[0];\n }\n}\n// ----\n// from_storage_to_static_array() -> 0, 7\n// from_storage_to_dynamic_array() -> 0x20, 1, 7\n// from_memory_to_static_array() -> 0, 7\n// from_memory_to_dynamic_array() -> 0x20, 1, 7\n// from_calldata_to_static_array((uint8)): 8 -> 0, 8\n// from_calldata_to_dynamic_array((uint8)): 8 -> 0x20, 1, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1.sol b/examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1.sol new file mode 100644 index 00000000..b34ef779 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1.sol @@ -0,0 +1,43 @@ +pragma abicoder v1; +contract test { + enum E { A, B, C } + mapping(E => uint8) public table; + function set(E k, uint8 v) public { + table[k] = v; + } + function get(E k) public returns (uint8) { + return this.table(k); + } +} +// ==== +// ABIEncoderV1Only: true +// EVMVersion: >=byzantium +// compileViaYul: false +// ---- +// table(uint8): 0 -> 0 +// table(uint8): 0x01 -> 0 +// table(uint8): 0xa7 -> 0 +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x01, 0xa1 -> +// table(uint8): 0 -> 0 +// table(uint8): 0x01 -> 0xa1 +// table(uint8): 0xa7 -> 0 +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x00, 0xef -> +// table(uint8): 0 -> 0xef +// table(uint8): 0x01 -> 0xa1 +// table(uint8): 0xa7 -> 0 +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x01, 0x05 -> +// table(uint8): 0 -> 0xef +// table(uint8): 0x01 -> 0x05 +// table(uint8): 0xa7 -> 0 +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 diff --git a/examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1_standard_input.json b/examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1_standard_input.json new file mode 100644 index 00000000..122c98a5 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_getter_v1/mapping_enum_key_getter_v1_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2.sol b/examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2.sol new file mode 100644 index 00000000..cd252a3a --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2.sol @@ -0,0 +1,39 @@ +pragma abicoder v2; +contract test { + enum E { A, B, C } + mapping(E => uint8) public table; + function set(E k, uint8 v) public { + table[k] = v; + } + function get(E k) public returns (uint8) { + return this.table(k); + } +} +// ---- +// table(uint8): 0 -> 0 +// table(uint8): 0x01 -> 0 +// table(uint8): 0xa7 -> FAILURE +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0xa1 -> +// table(uint8): 0 -> 0 +// table(uint8): 0x01 -> 0xa1 +// table(uint8): 0xa7 -> FAILURE +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x00, 0xef -> +// table(uint8): 0 -> 0xef +// table(uint8): 0x01 -> 0xa1 +// table(uint8): 0xa7 -> FAILURE +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0x05 -> +// table(uint8): 0 -> 0xef +// table(uint8): 0x01 -> 0x05 +// table(uint8): 0xa7 -> FAILURE +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> FAILURE diff --git a/examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2_standard_input.json b/examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2_standard_input.json new file mode 100644 index 00000000..6962316d --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_getter_v2/mapping_enum_key_getter_v2_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1.sol b/examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1.sol new file mode 100644 index 00000000..798ef812 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1.sol @@ -0,0 +1,40 @@ +pragma abicoder v1; +enum E { A, B, C } +library L { + function get(mapping(E => uint8) storage table, E k) external returns (uint8) { + return table[k]; + } + function set(mapping(E => uint8) storage table, E k, uint8 v) external { + table[k] = v; + } +} +contract test { + mapping(E => uint8) table; + function get(E k) public returns (uint8 v) { + return L.get(table, k); + } + function set(E k, uint8 v) public { + L.set(table, k, v); + } +} +// ==== +// EVMVersion: >=byzantium +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// library: L +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x01, 0xa1 -> +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x00, 0xef -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x01, 0x05 -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 diff --git a/examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1_standard_input.json b/examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1_standard_input.json new file mode 100644 index 00000000..cbe3232b --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_library_v1/mapping_enum_key_library_v1_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2.sol b/examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2.sol new file mode 100644 index 00000000..87676aa0 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2.sol @@ -0,0 +1,39 @@ +pragma abicoder v2; + +enum E { A, B, C } +library L { + function get(mapping(E => uint8) storage table, E k) external returns (uint8) { + return table[k]; + } + function set(mapping(E => uint8) storage table, E k, uint8 v) external { + table[k] = v; + } +} +contract test { + mapping(E => uint8) table; + function get(E k) public returns (uint8 v) { + return L.get(table, k); + } + function set(E k, uint8 v) public { + L.set(table, k, v); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// library: L +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0xa1 -> +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x00, 0xef -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0x05 -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> FAILURE diff --git a/examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2_standard_input.json b/examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2_standard_input.json new file mode 100644 index 00000000..103e9296 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_library_v2/mapping_enum_key_library_v2_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1.sol b/examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1.sol new file mode 100644 index 00000000..934ce7d1 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1.sol @@ -0,0 +1,33 @@ +pragma abicoder v1; +enum E { A, B, C } +contract test { + mapping(E => uint8) table; + function get(E k) public returns (uint8 v) { + return table[k]; + } + function set(E k, uint8 v) public { + table[k] = v; + } +} +// ==== +// EVMVersion: >=byzantium +// ABIEncoderV1Only: true +// compileViaYul: false +// ---- +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0x02 -> 0 +// get(uint8): 0x03 -> FAILURE, hex"4e487b71", 33 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x01, 0xa1 -> +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x00, 0xef -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 +// set(uint8,uint8): 0x01, 0x05 -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> FAILURE, hex"4e487b71", 33 diff --git a/examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1_standard_input.json b/examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1_standard_input.json new file mode 100644 index 00000000..7453c3cf --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_v1/mapping_enum_key_v1_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2.sol b/examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2.sol new file mode 100644 index 00000000..a35fdd22 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2.sol @@ -0,0 +1,31 @@ +pragma abicoder v2; +enum E { A, B, C } +contract test { + mapping(E => uint8) table; + function get(E k) public returns (uint8 v) { + return table[k]; + } + function set(E k, uint8 v) public { + table[k] = v; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0x02 -> 0 +// get(uint8): 0x03 -> FAILURE +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0xa1 -> +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x00, 0xef -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0x05 -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> FAILURE diff --git a/examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2_standard_input.json b/examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2_standard_input.json new file mode 100644 index 00000000..0844806f --- /dev/null +++ b/examples/test/semanticTests/types_mapping_enum_key_v2/mapping_enum_key_v2_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_simple/mapping_simple.sol b/examples/test/semanticTests/types_mapping_simple/mapping_simple.sol new file mode 100644 index 00000000..4da4c5b1 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_simple/mapping_simple.sol @@ -0,0 +1,25 @@ +contract test { + mapping(uint8 => uint8) table; + function get(uint8 k) public returns (uint8 v) { + return table[k]; + } + function set(uint8 k, uint8 v) public { + table[k] = v; + } +} +// ---- +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0 +// get(uint8): 0xa7 -> 0 +// set(uint8,uint8): 0x01, 0xa1 -> +// get(uint8): 0 -> 0 +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> 0 +// set(uint8,uint8): 0x00, 0xef -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0xa1 +// get(uint8): 0xa7 -> 0 +// set(uint8,uint8): 0x01, 0x05 -> +// get(uint8): 0 -> 0xef +// get(uint8): 0x01 -> 0x05 +// get(uint8): 0xa7 -> 0 diff --git a/examples/test/semanticTests/types_mapping_simple/mapping_simple_standard_input.json b/examples/test/semanticTests/types_mapping_simple/mapping_simple_standard_input.json new file mode 100644 index 00000000..17cc6c54 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_simple/mapping_simple_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage.sol b/examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage.sol new file mode 100644 index 00000000..a8a8fca4 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage.sol @@ -0,0 +1,25 @@ +type A is uint; +type B is uint; + +library L { + function f(mapping(A=>B) storage _m, B _v) public { _m[A.wrap(uint(2))] = _v; } + function f(mapping(uint=>uint) storage _m, uint _v) public { _m[uint(3)] = _v; } +} + +contract C { + mapping(uint=>uint) uintMap; + mapping(A=>B) abMap; + + function testAB() public returns (bool) { + L.f(abMap, B.wrap(3)); + return B.unwrap(abMap[A.wrap(uint(2))]) == 3; + } + function testUint() public returns (bool) { + L.f(uintMap, 4); + return uintMap[3] == 4; + } +} +// ---- +// library: L +// testAB() -> true +// testUint() -> true diff --git a/examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage_standard_input.json b/examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage_standard_input.json new file mode 100644 index 00000000..3da35434 --- /dev/null +++ b/examples/test/semanticTests/types_mapping_user_defined_types_mapping_storage/user_defined_types_mapping_storage_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "copy_struct_to_array_stored_in_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8 x;\n }\n\n constructor() {\n s = S({x: 7});\n m2[0].push();\n }\n\n S s;\n\n mapping (uint8 => S[2]) m1;\n mapping (uint8 => S[]) m2;\n\n function from_storage_to_static_array() public returns (S[2] memory) {\n m1[0][1] = s;\n return m1[0];\n }\n\n function from_storage_to_dynamic_array() public returns (S[] memory) {\n m2[0][0] = s;\n return m2[0];\n }\n\n function from_memory_to_static_array() public returns (S[2] memory) {\n S memory sLocal = s;\n m1[0][1] = sLocal;\n return m1[0];\n }\n\n function from_memory_to_dynamic_array() public returns (S[] memory) {\n S memory sLocal = s;\n m2[0][0] = sLocal;\n return m2[0];\n }\n\n function from_calldata_to_static_array(S calldata sCalldata) public returns (S[2] memory) {\n m1[0][1] = sCalldata;\n return m1[0];\n }\n\n function from_calldata_to_dynamic_array(S calldata sCalldata) public returns (S[] memory) {\n m2[0][0] = sCalldata;\n return m2[0];\n }\n}\n// ----\n// from_storage_to_static_array() -> 0, 7\n// from_storage_to_dynamic_array() -> 0x20, 1, 7\n// from_memory_to_static_array() -> 0, 7\n// from_memory_to_dynamic_array() -> 0x20, 1, 7\n// from_calldata_to_static_array((uint8)): 8 -> 0, 8\n// from_calldata_to_dynamic_array((uint8)): 8 -> 0x20, 1, 8\n" + }, + "copy_from_mapping_to_mapping.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint8[3] x;\n uint8[][] y;\n uint16 z;\n }\n\n mapping (uint8 => S) src;\n mapping (uint8 => S) dst;\n\n constructor() {\n uint8[] memory d = new uint8[](2);\n d[0] = 3;\n d[1] = 4;\n\n uint8[][] memory y = new uint8[][](2);\n y[0] = d;\n y[1] = d;\n\n src[0] = S({x: [7, 8, 9], y: y, z: 13});\n }\n\n function f() public returns (S memory) {\n dst[0] = src[0];\n return dst[0];\n }\n}\n// ----\n// f() -> 0x20, 7, 8, 9, 0xa0, 13, 2, 0x40, 0xa0, 2, 3, 4, 2, 3, 4\n// gas irOptimized: 197102\n// gas legacy: 199887\n// gas legacyOptimized: 196845\n" + }, + "user_defined_types_mapping_storage.sol": { + "content": "type A is uint;\ntype B is uint;\n\nlibrary L {\n function f(mapping(A=>B) storage _m, B _v) public { _m[A.wrap(uint(2))] = _v; }\n function f(mapping(uint=>uint) storage _m, uint _v) public { _m[uint(3)] = _v; }\n}\n\ncontract C {\n\tmapping(uint=>uint) uintMap;\n\tmapping(A=>B) abMap;\n\n\tfunction testAB() public returns (bool) {\n\t\tL.f(abMap, B.wrap(3));\n\t\treturn B.unwrap(abMap[A.wrap(uint(2))]) == 3;\n\t}\n\tfunction testUint() public returns (bool) {\n\t\tL.f(uintMap, 4);\n\t\treturn uintMap[3] == 4;\n\t}\n}\n// ----\n// library: L\n// testAB() -> true\n// testUint() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_nested_tuples/nested_tuples.sol b/examples/test/semanticTests/types_nested_tuples/nested_tuples.sol new file mode 100644 index 00000000..32203a9c --- /dev/null +++ b/examples/test/semanticTests/types_nested_tuples/nested_tuples.sol @@ -0,0 +1,34 @@ +contract test { + function f0() public returns(int, bool) { + int a; + bool b; + ((a, b)) = (2, true); + return (a, b); + } + function f1() public returns(int) { + int a; + (((a, ), )) = ((1, 2) ,3); + return a; + } + function f2() public returns(int) { + int a; + (((, a),)) = ((1, 2), 3); + return a; + } + function f3() public returns(int) { + int a = 3; + ((, ), ) = ((7, 8), 9); + return a; + } + function f4() public returns(int) { + int a; + (a, ) = (4, (8, 16, 32)); + return a; + } +} +// ---- +// f0() -> 2, true +// f1() -> 1 +// f2() -> 2 +// f3() -> 3 +// f4() -> 4 diff --git a/examples/test/semanticTests/types_nested_tuples/nested_tuples_standard_input.json b/examples/test/semanticTests/types_nested_tuples/nested_tuples_standard_input.json new file mode 100644 index 00000000..78d2661b --- /dev/null +++ b/examples/test/semanticTests/types_nested_tuples/nested_tuples_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_packing_signed_types/packing_signed_types.sol b/examples/test/semanticTests/types_packing_signed_types/packing_signed_types.sol new file mode 100644 index 00000000..2d2e0e16 --- /dev/null +++ b/examples/test/semanticTests/types_packing_signed_types/packing_signed_types.sol @@ -0,0 +1,8 @@ +contract test { + function run() public returns(int8 y) { + uint8 x = 0xfa; + return int8(x); + } +} +// ---- +// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa diff --git a/examples/test/semanticTests/types_packing_signed_types/packing_signed_types_standard_input.json b/examples/test/semanticTests/types_packing_signed_types/packing_signed_types_standard_input.json new file mode 100644 index 00000000..fb1790e3 --- /dev/null +++ b/examples/test/semanticTests/types_packing_signed_types/packing_signed_types_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types.sol b/examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types.sol new file mode 100644 index 00000000..8b500cca --- /dev/null +++ b/examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types.sol @@ -0,0 +1,10 @@ +contract test { + function run(bool a, uint32 b, uint64 c) public returns(uint256 y) { + if (a) y = 1; + y = y * 0x100000000 | ~b; + y = y * 0x10000000000000000 | ~c; + } +} +// ---- +// run(bool,uint32,uint64): true, 0x0f0f0f0f, 0xf0f0f0f0f0f0f0f0 +// -> 0x0000000000000000000000000000000000000001f0f0f0f00f0f0f0f0f0f0f0f diff --git a/examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types_standard_input.json b/examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types_standard_input.json new file mode 100644 index 00000000..2aa48af1 --- /dev/null +++ b/examples/test/semanticTests/types_packing_unpacking_types/packing_unpacking_types_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + }, + "mapping_contract_key.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return table[k];\n }\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "tuple_assign_multi_slot_grow.sol": { + "content": "contract C {\n\n\tfunction f() public pure returns (uint, uint, uint) {\n\t\tbytes memory a; bytes memory b; bytes memory c;\n\t\t(a, (b, c)) = (\"0\", (\"1\", \"2\"));\n\t\treturn (uint8(a[0]), uint8(b[0]), uint8(c[0]));\n\t}\n\n}\n// ----\n// f() -> 0x30, 0x31, 0x32\n" + }, + "convert_fixed_bytes_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"abcd\"\n" + }, + "convert_fixed_bytes_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes2 ret) {\n return bytes2(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"ab\"\n" + }, + "packing_unpacking_types.sol": { + "content": "contract test {\n function run(bool a, uint32 b, uint64 c) public returns(uint256 y) {\n if (a) y = 1;\n y = y * 0x100000000 | ~b;\n y = y * 0x10000000000000000 | ~c;\n }\n}\n// ----\n// run(bool,uint32,uint64): true, 0x0f0f0f0f, 0xf0f0f0f0f0f0f0f0\n// -> 0x0000000000000000000000000000000000000001f0f0f0f00f0f0f0f0f0f0f0f\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_strings/strings.sol b/examples/test/semanticTests/types_strings/strings.sol new file mode 100644 index 00000000..f76116bb --- /dev/null +++ b/examples/test/semanticTests/types_strings/strings.sol @@ -0,0 +1,16 @@ +contract test { + function fixedBytesHex() public returns(bytes32 ret) { + return hex"aabb00ff"; + } + function fixedBytes() public returns(bytes32 ret) { + return "abc\x00\xff__"; + } + function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) { + oneRet = one; + large = small; + } +} +// ---- +// fixedBytesHex() -> "\xaa\xbb\x00\xff" +// fixedBytes() -> "abc\x00\xff__" +// pipeThrough(bytes2,bool): "\x00\x02", true -> "\x00\x02", true diff --git a/examples/test/semanticTests/types_strings/strings_standard_input.json b/examples/test/semanticTests/types_strings/strings_standard_input.json new file mode 100644 index 00000000..c41c7954 --- /dev/null +++ b/examples/test/semanticTests/types_strings/strings_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param.sol b/examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param.sol new file mode 100644 index 00000000..2040df1d --- /dev/null +++ b/examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param.sol @@ -0,0 +1,24 @@ +struct S { + mapping (uint => uint) m; +} + +abstract contract A { + constructor (S storage s) { + s.m[5] = 16; + } +} + +contract C is A { + mapping(uint => S) m; + + constructor() A(m[1]) { + } + + function getM(uint a, uint b) external returns (uint) { + return m[a].m[b]; + } +} +// ---- +// getM(uint256,uint256): 0, 0 -> 0 +// getM(uint256,uint256): 1, 5 -> 0x10 +// getM(uint256,uint256): 1, 0 -> 0 diff --git a/examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param_standard_input.json b/examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param_standard_input.json new file mode 100644 index 00000000..1a2c9189 --- /dev/null +++ b/examples/test/semanticTests/types_struct_mapping_abstract_constructor_param/struct_mapping_abstract_constructor_param_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow.sol b/examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow.sol new file mode 100644 index 00000000..6574dcb5 --- /dev/null +++ b/examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow.sol @@ -0,0 +1,11 @@ +contract C { + + function f() public pure returns (uint, uint, uint) { + bytes memory a; bytes memory b; bytes memory c; + (a, (b, c)) = ("0", ("1", "2")); + return (uint8(a[0]), uint8(b[0]), uint8(c[0])); + } + +} +// ---- +// f() -> 0x30, 0x31, 0x32 diff --git a/examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow_standard_input.json b/examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow_standard_input.json new file mode 100644 index 00000000..3ab4b8e2 --- /dev/null +++ b/examples/test/semanticTests/types_tuple_assign_multi_slot_grow/tuple_assign_multi_slot_grow_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + }, + "mapping_contract_key.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return table[k];\n }\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "tuple_assign_multi_slot_grow.sol": { + "content": "contract C {\n\n\tfunction f() public pure returns (uint, uint, uint) {\n\t\tbytes memory a; bytes memory b; bytes memory c;\n\t\t(a, (b, c)) = (\"0\", (\"1\", \"2\"));\n\t\treturn (uint8(a[0]), uint8(b[0]), uint8(c[0]));\n\t}\n\n}\n// ----\n// f() -> 0x30, 0x31, 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup.sol b/examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup.sol new file mode 100644 index 00000000..d3d2b01b --- /dev/null +++ b/examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup.sol @@ -0,0 +1,5 @@ +contract Test { + function test() public returns (uint ret) { return uint(uint160(address(uint160(uint128(type(uint200).max))))); } +} +// ---- +// test() -> 0xffffffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup_standard_input.json b/examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup_standard_input.json new file mode 100644 index 00000000..faff964c --- /dev/null +++ b/examples/test/semanticTests/types_type_conversion_cleanup/type_conversion_cleanup_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "convert_uint_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function UintToBytes(uint16 h) public returns (bytes8 s) {\n return bytes8(uint64(h));\n }\n}\n// ----\n// UintToBytes(uint16): 0x6162 -> \"\\x00\\x00\\x00\\x00\\x00\\x00ab\"\n" + }, + "mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n constructor (mapping (uint => uint) storage m) {\n m[5] = 20;\n }\n}\n\ncontract C is A {\n mapping (uint => uint) public m;\n\n constructor() A(m) {\n }\n}\n// ----\n// m(uint256): 1 -> 0\n// m(uint256): 5 -> 20\n" + }, + "mapping_enum_key_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE, hex\"4e487b71\", 33\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "assign_calldata_value_type.sol": { + "content": "contract C {\n function f(uint256 x) public pure returns (uint256, uint256) {\n uint256 b = x;\n x = 42;\n return (x, b);\n }\n}\n// ----\n// f(uint256): 23 -> 42, 23\n" + }, + "convert_uint_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function uintToBytes(uint32 h) public returns (bytes2 s) {\n return bytes2(uint16(h));\n }\n}\n// ----\n// uintToBytes(uint32): 0x61626364 -> \"cd\"\n" + }, + "mapping_enum_key_v2.sol": { + "content": "pragma abicoder v2;\nenum E { A, B, C }\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return table[k];\n }\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0x02 -> 0\n// get(uint8): 0x03 -> FAILURE\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "mapping_contract_key_getter.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) public table;\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n function get(A k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// table(address): 0 -> 0\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0xa1\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// table(address): 0 -> 0xef\n// table(address): 0x01 -> 0x05\n// table(address): 0xa7 -> 0\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "packing_signed_types.sol": { + "content": "contract test {\n function run() public returns(int8 y) {\n uint8 x = 0xfa;\n return int8(x);\n }\n}\n// ----\n// run() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa\n" + }, + "external_function_to_address.sol": { + "content": "contract C {\n function f() public returns (bool) {\n return this.f.address == address(this);\n }\n function g(function() external cb) public returns (address) {\n return cb.address;\n }\n}\n// ----\n// f() -> true\n// g(function): hex\"00000000000000000000000000000000000004226121ff00000000000000000\" -> 0x42\n" + }, + "convert_fixed_bytes_to_uint_same_type.sol": { + "content": "contract Test {\n function bytesToUint(bytes32 s) public returns (uint256 h) {\n return uint(s);\n }\n}\n// ----\n// bytesToUint(bytes32): \"abc2\" -> left(0x61626332)\n" + }, + "convert_uint_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function uintToBytes(uint256 h) public returns (bytes32 s) {\n return bytes32(h);\n }\n}\n// ----\n// uintToBytes(uint256): left(0x616263) -> left(0x616263)\n" + }, + "mapping_contract_key_library.sol": { + "content": "interface A {}\nlibrary L {\n function get(mapping(A => uint8) storage table, A k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(A => uint8) storage table, A k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(A k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ----\n// library: L\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "convert_fixed_bytes_to_uint_greater_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint64 h) {\n return uint64(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x61626364\n" + }, + "convert_fixed_bytes_to_uint_smaller_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes4 s) public returns (uint16 h) {\n return uint16(uint32(s));\n }\n}\n// ----\n// bytesToUint(bytes4): \"abcd\" -> 0x6364\n" + }, + "mapping_enum_key_getter_v1.sol": { + "content": "pragma abicoder v1;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ====\n// ABIEncoderV1Only: true\n// EVMVersion: >=byzantium\n// compileViaYul: false\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> 0\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "array_mapping_abstract_constructor_param.sol": { + "content": "abstract contract A {\n\tconstructor (mapping (uint => uint) [] storage m) {\n\t\tm.push();\n\t\tm[0][1] = 2;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => mapping (uint => uint) []) public m;\n\n\tconstructor() A(m[1]) {\n\t}\n}\n// ----\n// m(uint256,uint256,uint256): 0, 0, 0 -> FAILURE\n// m(uint256,uint256,uint256): 1, 0, 1 -> 2\n// m(uint256,uint256,uint256): 1, 0, 5 -> 0\n" + }, + "mapping_enum_key_getter_v2.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n function get(E k) public returns (uint8) {\n return this.table(k);\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "convert_fixed_bytes_to_uint_same_min_size.sol": { + "content": "contract Test {\n function bytesToUint(bytes1 s) public returns (uint8 h) {\n return uint8(s);\n }\n}\n// ----\n// bytesToUint(bytes1): \"a\" -> 0x61\n" + }, + "nested_tuples.sol": { + "content": "contract test {\n function f0() public returns(int, bool) {\n int a;\n bool b;\n ((a, b)) = (2, true);\n return (a, b);\n }\n function f1() public returns(int) {\n int a;\n (((a, ), )) = ((1, 2) ,3);\n return a;\n }\n function f2() public returns(int) {\n int a;\n (((, a),)) = ((1, 2), 3);\n return a;\n }\n function f3() public returns(int) {\n int a = 3;\n ((, ), ) = ((7, 8), 9);\n return a;\n }\n function f4() public returns(int) {\n int a;\n (a, ) = (4, (8, 16, 32));\n return a;\n }\n}\n// ----\n// f0() -> 2, true\n// f1() -> 1\n// f2() -> 2\n// f3() -> 3\n// f4() -> 4\n" + }, + "convert_uint_to_fixed_bytes_same_min_size.sol": { + "content": "contract Test {\n function UintToBytes(uint8 h) public returns (bytes1 s) {\n return bytes1(h);\n }\n}\n// ----\n// UintToBytes(uint8): 0x61 -> \"a\"\n" + }, + "mapping_enum_key_library_v1.sol": { + "content": "pragma abicoder v1;\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ABIEncoderV1Only: true\n// compileViaYul: false\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE, hex\"4e487b71\", 33\n" + }, + "mapping_simple.sol": { + "content": "contract test {\n mapping(uint8 => uint8) table;\n function get(uint8 k) public returns (uint8 v) {\n return table[k];\n }\n function set(uint8 k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> 0\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> 0\n" + }, + "strings.sol": { + "content": "contract test {\n function fixedBytesHex() public returns(bytes32 ret) {\n return hex\"aabb00ff\";\n }\n function fixedBytes() public returns(bytes32 ret) {\n return \"abc\\x00\\xff__\";\n }\n function pipeThrough(bytes2 small, bool one) public returns(bytes16 large, bool oneRet) {\n oneRet = one;\n large = small;\n }\n}\n// ----\n// fixedBytesHex() -> \"\\xaa\\xbb\\x00\\xff\"\n// fixedBytes() -> \"abc\\x00\\xff__\"\n// pipeThrough(bytes2,bool): \"\\x00\\x02\", true -> \"\\x00\\x02\", true\n" + }, + "mapping_enum_key_library_v2.sol": { + "content": "pragma abicoder v2;\n\nenum E { A, B, C }\nlibrary L {\n function get(mapping(E => uint8) storage table, E k) external returns (uint8) {\n return table[k];\n }\n function set(mapping(E => uint8) storage table, E k, uint8 v) external {\n table[k] = v;\n }\n}\ncontract test {\n mapping(E => uint8) table;\n function get(E k) public returns (uint8 v) {\n return L.get(table, k);\n }\n function set(E k, uint8 v) public {\n L.set(table, k, v);\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// library: L\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// get(uint8): 0 -> 0\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0xa1\n// get(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// get(uint8): 0 -> 0xef\n// get(uint8): 0x01 -> 0x05\n// get(uint8): 0xa7 -> FAILURE\n" + }, + "struct_mapping_abstract_constructor_param.sol": { + "content": "struct S {\n\tmapping (uint => uint) m;\n}\n\nabstract contract A {\n\tconstructor (S storage s) {\n\t\ts.m[5] = 16;\n\t}\n}\n\ncontract C is A {\n\tmapping(uint => S) m;\n\n\tconstructor() A(m[1]) {\n\t}\n\n\tfunction getM(uint a, uint b) external returns (uint) {\n\t\treturn m[a].m[b];\n\t}\n}\n// ----\n// getM(uint256,uint256): 0, 0 -> 0\n// getM(uint256,uint256): 1, 5 -> 0x10\n// getM(uint256,uint256): 1, 0 -> 0\n" + }, + "convert_fixed_bytes_to_fixed_bytes_greater_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes2 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes2): \"ab\" -> \"ab\"\n" + }, + "mapping_contract_key.sol": { + "content": "interface A {}\ncontract test {\n mapping(A => uint8) table;\n function get(A k) public returns (uint8 v) {\n return table[k];\n }\n function set(A k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0xa1 ->\n// get(address): 0 -> 0\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x00, 0xef ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0xa1\n// get(address): 0xa7 -> 0\n// set(address,uint8): 0x01, 0x05 ->\n// get(address): 0 -> 0xef\n// get(address): 0x01 -> 0x05\n// get(address): 0xa7 -> 0\n" + }, + "tuple_assign_multi_slot_grow.sol": { + "content": "contract C {\n\n\tfunction f() public pure returns (uint, uint, uint) {\n\t\tbytes memory a; bytes memory b; bytes memory c;\n\t\t(a, (b, c)) = (\"0\", (\"1\", \"2\"));\n\t\treturn (uint8(a[0]), uint8(b[0]), uint8(c[0]));\n\t}\n\n}\n// ----\n// f() -> 0x30, 0x31, 0x32\n" + }, + "convert_fixed_bytes_to_fixed_bytes_same_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes4 ret) {\n return bytes4(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"abcd\"\n" + }, + "convert_fixed_bytes_to_fixed_bytes_smaller_size.sol": { + "content": "contract Test {\n function bytesToBytes(bytes4 input) public returns (bytes2 ret) {\n return bytes2(input);\n }\n}\n// ----\n// bytesToBytes(bytes4): \"abcd\" -> \"ab\"\n" + }, + "packing_unpacking_types.sol": { + "content": "contract test {\n function run(bool a, uint32 b, uint64 c) public returns(uint256 y) {\n if (a) y = 1;\n y = y * 0x100000000 | ~b;\n y = y * 0x10000000000000000 | ~c;\n }\n}\n// ----\n// run(bool,uint32,uint64): true, 0x0f0f0f0f, 0xf0f0f0f0f0f0f0f0\n// -> 0x0000000000000000000000000000000000000001f0f0f0f00f0f0f0f0f0f0f0f\n" + }, + "type_conversion_cleanup.sol": { + "content": "contract Test {\n function test() public returns (uint ret) { return uint(uint160(address(uint160(uint128(type(uint200).max))))); }\n}\n// ----\n// test() -> 0xffffffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/underscore_as_function/as_function.sol b/examples/test/semanticTests/underscore_as_function/as_function.sol new file mode 100644 index 00000000..be60a01b --- /dev/null +++ b/examples/test/semanticTests/underscore_as_function/as_function.sol @@ -0,0 +1,18 @@ +contract C { + function _() public pure returns (uint) { + return 88; + } + + function g() public pure returns (uint){ + return _(); + } + + function h() public pure returns (uint) { + _; + return 33; + } +} +// ---- +// _() -> 88 +// g() -> 88 +// h() -> 33 diff --git a/examples/test/semanticTests/underscore_as_function/as_function_standard_input.json b/examples/test/semanticTests/underscore_as_function/as_function_standard_input.json new file mode 100644 index 00000000..95feb92e --- /dev/null +++ b/examples/test/semanticTests/underscore_as_function/as_function_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "as_function.sol": { + "content": "contract C {\n function _() public pure returns (uint) {\n return 88;\n }\n\n function g() public pure returns (uint){\n return _();\n }\n\n function h() public pure returns (uint) {\n _;\n return 33;\n }\n}\n// ----\n// _() -> 88\n// g() -> 88\n// h() -> 33\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor.sol b/examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor.sol new file mode 100644 index 00000000..e4e6453c --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor.sol @@ -0,0 +1,23 @@ +contract C { + + function() internal storedFn; + + bool flag; + + constructor() { + if (!flag) { + flag = true; + function() internal invalid; + storedFn = invalid; + invalid(); + } + } + function f() public pure {} +} +contract Test { + function f() public { + new C(); + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor_standard_input.json b/examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor_standard_input.json new file mode 100644 index 00000000..6aa05462 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_invalidInConstructor/invalidInConstructor_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "store2.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n function() internal storedFn;\n uint public x;\n\n constructor() {\n uint _y1;\n uint _y2;\n uint _y3;\n uint _y4;\n uint _y5;\n uint _y6;\n uint _y7;\n uint _y8;\n uint _y9;\n uint _y10;\n uint _y11;\n uint _y12;\n uint _y13;\n uint _y14;\n\n\n function() internal invalid;\n storedFn = invalid;\n }\n\n function run() public {\n // this did not always cause revert in the past\n storedFn();\n }\n\n function z() public {\n x++;\n }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_legacy.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z != 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> true\n" + }, + "storeInConstructor.sol": { + "content": "contract InvalidTest {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n function() internal invalid;\n storedFn = invalid;\n }\n function f() public returns (uint) {\n if (flag) return 2;\n flag = true;\n storedFn();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_via_yul.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z == 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "invalidInConstructor.sol": { + "content": "contract C {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n if (!flag) {\n flag = true;\n function() internal invalid;\n storedFn = invalid;\n invalid();\n }\n }\n function f() public pure {}\n}\ncontract Test {\n function f() public {\n new C();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor.sol b/examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor.sol new file mode 100644 index 00000000..fbaca1a6 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor.sol @@ -0,0 +1,23 @@ +contract C { + + function() internal storedFn; + + bool flag; + + constructor() { + if (!flag) { + flag = true; + function() internal invalid; + storedFn = invalid; + storedFn(); + } + } + function f() public pure {} +} +contract Test { + function f() public { + new C(); + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor_standard_input.json b/examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor_standard_input.json new file mode 100644 index 00000000..cea97bc6 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_invalidStoredInConstructor/invalidStoredInConstructor_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "store2.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n function() internal storedFn;\n uint public x;\n\n constructor() {\n uint _y1;\n uint _y2;\n uint _y3;\n uint _y4;\n uint _y5;\n uint _y6;\n uint _y7;\n uint _y8;\n uint _y9;\n uint _y10;\n uint _y11;\n uint _y12;\n uint _y13;\n uint _y14;\n\n\n function() internal invalid;\n storedFn = invalid;\n }\n\n function run() public {\n // this did not always cause revert in the past\n storedFn();\n }\n\n function z() public {\n x++;\n }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_legacy.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z != 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> true\n" + }, + "storeInConstructor.sol": { + "content": "contract InvalidTest {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n function() internal invalid;\n storedFn = invalid;\n }\n function f() public returns (uint) {\n if (flag) return 2;\n flag = true;\n storedFn();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_via_yul.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z == 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "invalidInConstructor.sol": { + "content": "contract C {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n if (!flag) {\n flag = true;\n function() internal invalid;\n storedFn = invalid;\n invalid();\n }\n }\n function f() public pure {}\n}\ncontract Test {\n function f() public {\n new C();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "invalidStoredInConstructor.sol": { + "content": "contract C {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n if (!flag) {\n flag = true;\n function() internal invalid;\n storedFn = invalid;\n storedFn();\n }\n }\n function f() public pure {}\n}\ncontract Test {\n function f() public {\n new C();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_store2/store2.sol b/examples/test/semanticTests/uninitializedFunctionPointer_store2/store2.sol new file mode 100644 index 00000000..1c1e596a --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_store2/store2.sol @@ -0,0 +1,39 @@ +pragma solidity >=0.4.0 <0.9.0; + +contract InvalidTest { + + function() internal storedFn; + uint public x; + + constructor() { + uint _y1; + uint _y2; + uint _y3; + uint _y4; + uint _y5; + uint _y6; + uint _y7; + uint _y8; + uint _y9; + uint _y10; + uint _y11; + uint _y12; + uint _y13; + uint _y14; + + + function() internal invalid; + storedFn = invalid; + } + + function run() public { + // this did not always cause revert in the past + storedFn(); + } + + function z() public { + x++; + } +} +// ---- +// run() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_store2/store2_standard_input.json b/examples/test/semanticTests/uninitializedFunctionPointer_store2/store2_standard_input.json new file mode 100644 index 00000000..ae88f7a5 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_store2/store2_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "store2.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n function() internal storedFn;\n uint public x;\n\n constructor() {\n uint _y1;\n uint _y2;\n uint _y3;\n uint _y4;\n uint _y5;\n uint _y6;\n uint _y7;\n uint _y8;\n uint _y9;\n uint _y10;\n uint _y11;\n uint _y12;\n uint _y13;\n uint _y14;\n\n\n function() internal invalid;\n storedFn = invalid;\n }\n\n function run() public {\n // this did not always cause revert in the past\n storedFn();\n }\n\n function z() public {\n x++;\n }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor.sol b/examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor.sol new file mode 100644 index 00000000..08a96792 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor.sol @@ -0,0 +1,19 @@ +contract InvalidTest { + + function() internal storedFn; + + bool flag; + + constructor() { + function() internal invalid; + storedFn = invalid; + } + function f() public returns (uint) { + if (flag) return 2; + flag = true; + storedFn(); + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x51 +// f() -> FAILURE, hex"4e487b71", 0x51 diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor_standard_input.json b/examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor_standard_input.json new file mode 100644 index 00000000..668563dc --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_storeInConstructor/storeInConstructor_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "store2.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n function() internal storedFn;\n uint public x;\n\n constructor() {\n uint _y1;\n uint _y2;\n uint _y3;\n uint _y4;\n uint _y5;\n uint _y6;\n uint _y7;\n uint _y8;\n uint _y9;\n uint _y10;\n uint _y11;\n uint _y12;\n uint _y13;\n uint _y14;\n\n\n function() internal invalid;\n storedFn = invalid;\n }\n\n function run() public {\n // this did not always cause revert in the past\n storedFn();\n }\n\n function z() public {\n x++;\n }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_legacy.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z != 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> true\n" + }, + "storeInConstructor.sol": { + "content": "contract InvalidTest {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n function() internal invalid;\n storedFn = invalid;\n }\n function f() public returns (uint) {\n if (flag) return 2;\n flag = true;\n storedFn();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy.sol b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy.sol new file mode 100644 index 00000000..1e5f9646 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy.sol @@ -0,0 +1,17 @@ +contract Test { + function() internal x; + function f() public returns (bool) { + function() internal t = x; + // The legacy codegen would use a specific function + // entry tag that always panics. + // Via Yul, the internal dispatch will panic instead. + uint z; + assembly { z := t } + assert(z != 0); + return true; + } +} +// ==== +// compileViaYul: false +// ---- +// f() -> true diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy_standard_input.json b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy_standard_input.json new file mode 100644 index 00000000..7fe8d1c3 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_legacy/uninitialized_internal_storage_function_legacy_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "store2.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n function() internal storedFn;\n uint public x;\n\n constructor() {\n uint _y1;\n uint _y2;\n uint _y3;\n uint _y4;\n uint _y5;\n uint _y6;\n uint _y7;\n uint _y8;\n uint _y9;\n uint _y10;\n uint _y11;\n uint _y12;\n uint _y13;\n uint _y14;\n\n\n function() internal invalid;\n storedFn = invalid;\n }\n\n function run() public {\n // this did not always cause revert in the past\n storedFn();\n }\n\n function z() public {\n x++;\n }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_legacy.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z != 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul.sol b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul.sol new file mode 100644 index 00000000..bf8eab8c --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul.sol @@ -0,0 +1,17 @@ +contract Test { + function() internal x; + function f() public returns (bool) { + function() internal t = x; + // The legacy codegen would use a specific function + // entry tag that always panics. + // Via Yul, the internal dispatch will panic instead. + uint z; + assembly { z := t } + assert(z == 0); + return true; + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> true diff --git a/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul_standard_input.json b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul_standard_input.json new file mode 100644 index 00000000..61e0ba14 --- /dev/null +++ b/examples/test/semanticTests/uninitializedFunctionPointer_uninitialized_internal_storage_function_via_yul/uninitialized_internal_storage_function_via_yul_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "store2.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract InvalidTest {\n\n function() internal storedFn;\n uint public x;\n\n constructor() {\n uint _y1;\n uint _y2;\n uint _y3;\n uint _y4;\n uint _y5;\n uint _y6;\n uint _y7;\n uint _y8;\n uint _y9;\n uint _y10;\n uint _y11;\n uint _y12;\n uint _y13;\n uint _y14;\n\n\n function() internal invalid;\n storedFn = invalid;\n }\n\n function run() public {\n // this did not always cause revert in the past\n storedFn();\n }\n\n function z() public {\n x++;\n }\n}\n// ----\n// run() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_legacy.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z != 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: false\n// ----\n// f() -> true\n" + }, + "storeInConstructor.sol": { + "content": "contract InvalidTest {\n\n function() internal storedFn;\n\n bool flag;\n\n constructor() {\n function() internal invalid;\n storedFn = invalid;\n }\n function f() public returns (uint) {\n if (flag) return 2;\n flag = true;\n storedFn();\n }\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n" + }, + "uninitialized_internal_storage_function_via_yul.sol": { + "content": "contract Test {\n\tfunction() internal x;\n\tfunction f() public returns (bool) {\n\t\tfunction() internal t = x;\n\t\t// The legacy codegen would use a specific function\n\t\t// entry tag that always panics.\n\t\t// Via Yul, the internal dispatch will panic instead.\n\t\tuint z;\n\t\tassembly { z := t }\n\t\tassert(z == 0);\n\t\treturn true;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug.sol b/examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug.sol new file mode 100644 index 00000000..87d4ef42 --- /dev/null +++ b/examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug.sol @@ -0,0 +1,15 @@ +contract C { + uint public x; + function f() public { + x = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug. + g(); + x = 2; + } + function g() internal { + if (msg.data.length > 4) return; + assembly { return(0, 0) } + } +} +// ---- +// f() -> +// x() -> 1 diff --git a/examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug_standard_input.json b/examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug_standard_input.json new file mode 100644 index 00000000..d85023cc --- /dev/null +++ b/examples/test/semanticTests/unused_store_storage_removal_bug_1/unused_store_storage_removal_bug_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "constructor_inheritance_init_order_2.sol": { + "content": "contract A {\n uint x = 42;\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// gas legacy: 100973\n// gas legacy code: 32600\n// gas legacyOptimized: 99137\n// gas legacyOptimized code: 16200\n// y() -> 42\n" + }, + "constructor_with_params_inheritance_2.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C(2, 1) {}\n// ----\n// i() -> 2\n// k() -> 1\n" + }, + "emit_two_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n}\n// ----\n// x() -> 1\n" + }, + "constructor_with_params_inheritance.sol": { + "content": "contract C {\n uint public i;\n uint public k;\n\n constructor(uint newI, uint newK) {\n i = newI;\n k = newK;\n }\n}\ncontract D is C {\n constructor(uint newI, uint newK) C(newI, newK + 1) {}\n}\n// ----\n// constructor(): 2, 0 ->\n// gas irOptimized: 101581\n// gas irOptimized code: 20200\n// gas legacy: 105192\n// gas legacy code: 32000\n// gas legacyOptimized: 101503\n// gas legacyOptimized code: 17000\n// i() -> 2\n// k() -> 1\n" + }, + "constructor_inheritance_init_order_3_legacy.sol": { + "content": "contract A {\n uint public x = 2;\n constructor(uint) {}\n function f() public returns(uint) { x = 4; }\n}\ncontract B is A {\n constructor() A(f()) {}\n}\n// ====\n// compileViaYul: false\n// ----\n// x() -> 4\n" + }, + "constructor_inheritance_init_order.sol": { + "content": "contract A {\n uint x;\n constructor() {\n x = 42;\n }\n function f() public returns(uint256) {\n return x;\n }\n}\ncontract B is A {\n uint public y = f();\n}\n// ====\n// compileViaYul: true\n// ----\n// constructor() ->\n// gas irOptimized: 99436\n// gas irOptimized code: 20200\n// y() -> 42\n" + }, + "empty_for_loop.sol": { + "content": "contract test {\n function f() public returns(uint ret) {\n ret = 1;\n for (;;) {\n ret += 1;\n if (ret >= 10) break;\n }\n }\n}\n// ----\n// f() -> 10\n" + }, + "emit_three_identical_events.sol": { + "content": "contract C {\n event Terminated();\n\n function terminate() external {\n emit Terminated();\n emit Terminated();\n emit Terminated();\n }\n}\n// ----\n// terminate() ->\n// ~ emit Terminated()\n// ~ emit Terminated()\n// ~ emit Terminated()" + }, + "state_variables_init_order_3.sol": { + "content": "contract A {\n uint public a = 42;\n uint public b;\n uint public c;\n constructor(uint x) {\n b = a;\n a = x;\n }\n function f(uint x) public returns (uint256) { c = x * 3; return 23; }\n}\ncontract B is A {\n uint public d = f(a);\n uint public e = b;\n uint public b_a;\n uint public b_b;\n uint public b_c;\n constructor() A(17) { b_a = a; b_b = b; b_c = c; }\n}\n// ====\n// compileViaYul: true\n// ----\n// a() -> 17\n// b() -> 42\n// c() -> 51\n// b_a() -> 17\n// b_b() -> 42\n// b_c() -> 51\n// d() -> 23\n// e() -> 42\n" + }, + "state_variables_init_order_2.sol": { + "content": "contract A {\n uint public x = 0;\n uint y = f();\n function f() public returns (uint256) {\n ++x;\n return 42;\n }\n}\ncontract B is A {\n uint public z;\n constructor() {\n z = x;\n }\n}\n// ----\n// z() -> 1\n" + }, + "unused_store_storage_removal_bug.sol": { + "content": "contract C {\n\tuint public x;\n\tfunction f() public {\n\t\tx = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.\n\t\tg();\n\t\tx = 2;\n\t}\n\tfunction g() internal {\n\t\tif (msg.data.length > 4) return;\n\t\tassembly { return(0, 0) }\n\t}\n}\n// ----\n// f() ->\n// x() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_abicodec/abicodec.sol b/examples/test/semanticTests/userDefinedValueType_abicodec/abicodec.sol new file mode 100644 index 00000000..c2f89ba8 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_abicodec/abicodec.sol @@ -0,0 +1,35 @@ +// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended. +contract C { + type MyInt is int; + function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) { + a = MyInt.wrap(-1); + b = MyInt.wrap(0); + c = MyInt.wrap(1); + d = x; + } + function g() external returns(bool) { + (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5))); + assert(success1); + + (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt)); + assert(MyInt.unwrap(a1) == -1); + assert(MyInt.unwrap(b1) == 0); + assert(MyInt.unwrap(c1) == 1); + assert(MyInt.unwrap(d1) == 5); + + (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5))); + assert(success2); + + (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int)); + assert(a2 == -1); + assert(b2 == 0); + assert(c2 == 1); + assert(d2 == -5); + + return true; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// g() -> true diff --git a/examples/test/semanticTests/userDefinedValueType_abicodec/abicodec_standard_input.json b/examples/test/semanticTests/userDefinedValueType_abicodec/abicodec_standard_input.json new file mode 100644 index 00000000..2fc79f63 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_abicodec/abicodec_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1.sol b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1.sol new file mode 100644 index 00000000..f41a9205 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1.sol @@ -0,0 +1,35 @@ +pragma abicoder v1; + +type MyBytes2 is bytes2; + +contract C { + function f(MyBytes2 val) external returns (bytes2 ret) { + assembly { + ret := val + } + } + + function g(bytes2 val) external returns (bytes2 ret) { + assembly { + ret := val + } + } + + function h(uint256 val) external returns (MyBytes2) { + MyBytes2 ret; + assembly { + ret := val + } + return ret; + } + +} +// ==== +// compileViaYul: false +// ---- +// f(bytes2): "ab" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// g(bytes2): "ab" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// f(bytes2): "abcdef" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// g(bytes2): "abcdef" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// h(uint256): "ab" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// h(uint256): "abcdef" -> 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1_standard_input.json b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1_standard_input.json new file mode 100644 index 00000000..4e28047c --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v1/assembly_access_bytes2_abicoder_v1_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "assembly_access_bytes2_abicoder_v1.sol": { + "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2.sol b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2.sol new file mode 100644 index 00000000..67e6107a --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2.sol @@ -0,0 +1,33 @@ +pragma abicoder v2; + +type MyBytes2 is bytes2; + +contract C { + function f(MyBytes2 val) external returns (bytes2 ret) { + assembly { + ret := val + } + } + + function g(bytes2 val) external returns (bytes2 ret) { + assembly { + ret := val + } + } + + function h(uint256 val) external returns (MyBytes2) { + MyBytes2 ret; + assembly { + ret := val + } + return ret; + } + +} +// ---- +// f(bytes2): "ab" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// g(bytes2): "ab" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// f(bytes2): "abcdef" -> FAILURE +// g(bytes2): "abcdef" -> FAILURE +// h(uint256): "ab" -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// h(uint256): "abcdef" -> 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2_standard_input.json b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2_standard_input.json new file mode 100644 index 00000000..0b8d913b --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_assembly_access_bytes2_abicoder_v2/assembly_access_bytes2_abicoder_v2_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_calldata/calldata.sol b/examples/test/semanticTests/userDefinedValueType_calldata/calldata.sol new file mode 100644 index 00000000..015d51c1 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_calldata/calldata.sol @@ -0,0 +1,63 @@ +pragma abicoder v2; +type MyAddress is address; + +contract C { + MyAddress[] public addresses; + function f(MyAddress[] calldata _addresses) external { + for (uint i = 0; i < _addresses.length; i++) { + MyAddress.unwrap(_addresses[i]).call(""); + } + addresses = _addresses; + } + function g(MyAddress[] memory _addresses) external { + for (uint i = 0; i < _addresses.length; i++) { + MyAddress.unwrap(_addresses[i]).call(""); + } + addresses = _addresses; + } + function test_f() external returns (bool) { + clean(); + MyAddress[] memory test = new MyAddress[](3); + test[0] = MyAddress.wrap(address(21)); + test[1] = MyAddress.wrap(address(22)); + test[2] = MyAddress.wrap(address(23)); + this.f(test); + test_equality(test); + return true; + } + function test_g() external returns (bool) { + clean(); + MyAddress[] memory test = new MyAddress[](5); + test[0] = MyAddress.wrap(address(24)); + test[1] = MyAddress.wrap(address(25)); + test[2] = MyAddress.wrap(address(26)); + test[3] = MyAddress.wrap(address(27)); + test[4] = MyAddress.wrap(address(28)); + this.g(test); + test_equality(test); + return true; + } + function clean() internal { + delete addresses; + } + function test_equality(MyAddress[] memory _addresses) internal view { + require (_addresses.length == addresses.length); + for (uint i = 0; i < _addresses.length; i++) { + require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i])); + } + } +} +// ---- +// test_f() -> true +// gas irOptimized: 122201 +// gas legacy: 125333 +// gas legacyOptimized: 122693 +// test_g() -> true +// gas irOptimized: 106408 +// gas legacy: 111133 +// gas legacyOptimized: 106925 +// addresses(uint256): 0 -> 0x18 +// addresses(uint256): 1 -> 0x19 +// addresses(uint256): 3 -> 0x1b +// addresses(uint256): 4 -> 0x1c +// addresses(uint256): 5 -> FAILURE diff --git a/examples/test/semanticTests/userDefinedValueType_calldata/calldata_standard_input.json b/examples/test/semanticTests/userDefinedValueType_calldata/calldata_standard_input.json new file mode 100644 index 00000000..eca63d5c --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_calldata/calldata_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage.sol b/examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage.sol new file mode 100644 index 00000000..c3d58811 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; + +type Small is uint16; +type Left is bytes2; +struct S { uint8 a; Small b; Left c; uint8 d; } + +contract C { + S public s; + Small[] public small; + Left[] public l; + function f(S calldata _s) external { + s = _s; + } + function g(Small[] calldata _small) external returns (Small[] memory) { + small = _small; + return small; + } + function h(Left[] calldata _left) external returns (Left[] memory) { + l = _left; + return l; + } +} +// ---- +// s() -> 0, 0, 0x00, 0 +// f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> +// gas irOptimized: 44405 +// gas legacy: 47200 +// gas legacyOptimized: 44923 +// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 +// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 +// gas irOptimized: 69097 +// gas legacy: 75466 +// gas legacyOptimized: 74255 +// small(uint256): 0 -> 1 +// small(uint256): 1 -> 2 +// h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" +// gas irOptimized: 69174 +// gas legacy: 75156 +// gas legacyOptimized: 74342 +// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage_standard_input.json b/examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage_standard_input.json new file mode 100644 index 00000000..5efb4c3c --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_calldata_to_storage/calldata_to_storage_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_cleanup/cleanup.sol b/examples/test/semanticTests/userDefinedValueType_cleanup/cleanup.sol new file mode 100644 index 00000000..cc165e87 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_cleanup/cleanup.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; +type MyUInt8 is uint8; + +// Note that this wraps from a uint256 +function wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } } +function unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } } + +contract C { + uint8 a; + MyUInt8 b; + uint8 c; + function ret() external returns(MyUInt8) { + return wrap(0x1ff); + } + function f(MyUInt8 x) external returns(MyUInt8) { + return x; + } + function mem() external returns (MyUInt8[] memory) { + MyUInt8[] memory x = new MyUInt8[](2); + x[0] = wrap(0x1ff); + x[1] = wrap(0xff); + require(unwrap(x[0]) == unwrap(x[1])); + assembly { + mstore(add(x, 0x20), 0x1ff) + } + require(unwrap(x[0]) == unwrap(x[1])); + return x; + } + function stor() external returns (uint8, MyUInt8, uint8) { + a = 1; + c = 2; + b = wrap(0x1ff); + return (a, b, c); + } +} +// ---- +// ret() -> 0xff +// f(uint8): 0x1ff -> FAILURE +// f(uint8): 0xff -> 0xff +// mem() -> 0x20, 2, 0xff, 0xff +// stor() -> 1, 0xff, 2 diff --git a/examples/test/semanticTests/userDefinedValueType_cleanup/cleanup_standard_input.json b/examples/test/semanticTests/userDefinedValueType_cleanup/cleanup_standard_input.json new file mode 100644 index 00000000..c233aea9 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_cleanup/cleanup_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1.sol b/examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1.sol new file mode 100644 index 00000000..727c6606 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1.sol @@ -0,0 +1,43 @@ +pragma abicoder v1; +type MyUInt8 is uint8; + +// Note that this wraps from a uint256 +function wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } } +function unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } } + +contract C { + uint8 a; + MyUInt8 b; + uint8 c; + function ret() external returns(MyUInt8) { + return wrap(0x1ff); + } + function f(MyUInt8 x) external returns(MyUInt8) { + return x; + } + function mem() external returns (MyUInt8[] memory) { + MyUInt8[] memory x = new MyUInt8[](2); + x[0] = wrap(0x1ff); + x[1] = wrap(0xff); + require(unwrap(x[0]) == unwrap(x[1])); + assembly { + mstore(add(x, 0x20), 0x1ff) + } + require(unwrap(x[0]) == unwrap(x[1])); + return x; + } + function stor() external returns (uint8, MyUInt8, uint8) { + a = 1; + c = 2; + b = wrap(0x1ff); + return (a, b, c); + } +} +// ==== +// compileViaYul: false +// ---- +// ret() -> 0xff +// f(uint8): 0x1ff -> 0xff +// f(uint8): 0xff -> 0xff +// mem() -> 0x20, 2, 0x01ff, 0xff +// stor() -> 1, 0xff, 2 diff --git a/examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1_standard_input.json b/examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1_standard_input.json new file mode 100644 index 00000000..c0079620 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_cleanup_abicoderv1/cleanup_abicoderv1_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_constant/constant.sol b/examples/test/semanticTests/userDefinedValueType_constant/constant.sol new file mode 100644 index 00000000..a1e58752 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_constant/constant.sol @@ -0,0 +1,11 @@ +type T is int224; +pragma solidity >= 0.0.0; +contract C { + T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776)); + T constant public t = s; + int224 constant public u = T.unwrap(t); +} +// ---- +// s() -> 165521356710917456517261742455526507355687727119203895813322792776 +// t() -> 165521356710917456517261742455526507355687727119203895813322792776 +// u() -> 165521356710917456517261742455526507355687727119203895813322792776 diff --git a/examples/test/semanticTests/userDefinedValueType_constant/constant_standard_input.json b/examples/test/semanticTests/userDefinedValueType_constant/constant_standard_input.json new file mode 100644 index 00000000..19a3bb20 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_constant/constant_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_conversion/conversion.sol b/examples/test/semanticTests/userDefinedValueType_conversion/conversion.sol new file mode 100644 index 00000000..24b316f9 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_conversion/conversion.sol @@ -0,0 +1,54 @@ +pragma abicoder v2; + +type MyUInt8 is uint8; +type MyInt8 is int8; +type MyUInt16 is uint16; + +contract C { + function f(uint a) external returns(MyUInt8) { + return MyUInt8.wrap(uint8(a)); + } + function g(uint a) external returns(MyInt8) { + return MyInt8.wrap(int8(int(a))); + } + function h(MyUInt8 a) external returns (MyInt8) { + return MyInt8.wrap(int8(MyUInt8.unwrap(a))); + } + function i(MyUInt8 a) external returns(MyUInt16) { + return MyUInt16.wrap(MyUInt8.unwrap(a)); + } + function j(MyUInt8 a) external returns (uint) { + return MyUInt8.unwrap(a); + } + function k(MyUInt8 a) external returns (MyUInt16) { + return MyUInt16.wrap(MyUInt8.unwrap(a)); + } + function m(MyUInt16 a) external returns (MyUInt8) { + return MyUInt8.wrap(uint8(MyUInt16.unwrap(a))); + } +} +// ---- +// f(uint256): 1 -> 1 +// f(uint256): 2 -> 2 +// f(uint256): 257 -> 1 +// g(uint256): 1 -> 1 +// g(uint256): 2 -> 2 +// g(uint256): 255 -> -1 +// g(uint256): 257 -> 1 +// h(uint8): 1 -> 1 +// h(uint8): 2 -> 2 +// h(uint8): 255 -> -1 +// h(uint8): 257 -> FAILURE +// i(uint8): 250 -> 250 +// j(uint8): 1 -> 1 +// j(uint8): 2 -> 2 +// j(uint8): 255 -> 0xff +// j(uint8): 257 -> FAILURE +// k(uint8): 1 -> 1 +// k(uint8): 2 -> 2 +// k(uint8): 255 -> 0xff +// k(uint8): 257 -> FAILURE +// m(uint16): 1 -> 1 +// m(uint16): 2 -> 2 +// m(uint16): 255 -> 0xff +// m(uint16): 257 -> 1 diff --git a/examples/test/semanticTests/userDefinedValueType_conversion/conversion_standard_input.json b/examples/test/semanticTests/userDefinedValueType_conversion/conversion_standard_input.json new file mode 100644 index 00000000..772e6fae --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_conversion/conversion_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1.sol b/examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1.sol new file mode 100644 index 00000000..e8fbfb24 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1.sol @@ -0,0 +1,56 @@ +pragma abicoder v1; + +type MyUInt8 is uint8; +type MyInt8 is int8; +type MyUInt16 is uint16; + +contract C { + function f(uint a) external returns(MyUInt8) { + return MyUInt8.wrap(uint8(a)); + } + function g(uint a) external returns(MyInt8) { + return MyInt8.wrap(int8(int(a))); + } + function h(MyUInt8 a) external returns (MyInt8) { + return MyInt8.wrap(int8(MyUInt8.unwrap(a))); + } + function i(MyUInt8 a) external returns(MyUInt16) { + return MyUInt16.wrap(MyUInt8.unwrap(a)); + } + function j(MyUInt8 a) external returns (uint) { + return MyUInt8.unwrap(a); + } + function k(MyUInt8 a) external returns (MyUInt16) { + return MyUInt16.wrap(MyUInt8.unwrap(a)); + } + function m(MyUInt16 a) external returns (MyUInt8) { + return MyUInt8.wrap(uint8(MyUInt16.unwrap(a))); + } +} +// ==== +// compileViaYul: false +// ---- +// f(uint256): 1 -> 1 +// f(uint256): 2 -> 2 +// f(uint256): 257 -> 1 +// g(uint256): 1 -> 1 +// g(uint256): 2 -> 2 +// g(uint256): 255 -> -1 +// g(uint256): 257 -> 1 +// h(uint8): 1 -> 1 +// h(uint8): 2 -> 2 +// h(uint8): 255 -> -1 +// h(uint8): 257 -> 1 +// i(uint8): 250 -> 250 +// j(uint8): 1 -> 1 +// j(uint8): 2 -> 2 +// j(uint8): 255 -> 0xff +// j(uint8): 257 -> 1 +// k(uint8): 1 -> 1 +// k(uint8): 2 -> 2 +// k(uint8): 255 -> 0xff +// k(uint8): 257 -> 1 +// m(uint16): 1 -> 1 +// m(uint16): 2 -> 2 +// m(uint16): 255 -> 0xff +// m(uint16): 257 -> 1 diff --git a/examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1_standard_input.json b/examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1_standard_input.json new file mode 100644 index 00000000..8856c0ef --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_conversion_abicoderv1/conversion_abicoderv1_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot.sol b/examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot.sol new file mode 100644 index 00000000..4936ba80 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot.sol @@ -0,0 +1,35 @@ +type MyUInt16 is uint16; +type MyBytes2 is bytes2; +contract C { + MyUInt16 public a = MyUInt16.wrap(13); + MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025))); + bytes2 public x; + function write_a() external { + uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001; + assembly { + sstore(a.slot, max) + } + } + function write_b() external { + uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001; + assembly { + sstore(b.slot, max) + } + } + function get_b(uint index) public returns (bytes1) { + return MyBytes2.unwrap(b)[index]; + } +} +// ---- +// a() -> 13 +// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000 +// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000 +// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000 +// get_b(uint256): 2 -> FAILURE, hex"4e487b71", 0x32 +// write_a() -> +// a() -> 0x2001 +// write_b() -> +// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000 +// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000 +// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000 +// get_b(uint256): 2 -> FAILURE, hex"4e487b71", 0x32 diff --git a/examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot_standard_input.json b/examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot_standard_input.json new file mode 100644 index 00000000..0b6994ad --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_dirty_slot/dirty_slot_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read.sol b/examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read.sol new file mode 100644 index 00000000..a5a51461 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read.sol @@ -0,0 +1,24 @@ +type MyInt8 is int8; +contract C { + MyInt8 public x = MyInt8.wrap(-5); + + /// The most significant bit is flipped to 0 + function create_dirty_slot() external { + uint mask = 2**255 -1; + assembly { + let value := sload(x.slot) + sstore(x.slot, and(mask, value)) + } + } + + function read_unclean_value() external returns (bytes32 ret) { + MyInt8 value = x; + assembly { + ret := value + } + } +} +// ---- +// x() -> -5 +// create_dirty_slot() -> +// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb diff --git a/examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read_standard_input.json b/examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read_standard_input.json new file mode 100644 index 00000000..a81c0c5a --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_dirty_uint8_read/dirty_uint8_read_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_erc20/erc20.sol b/examples/test/semanticTests/userDefinedValueType_erc20/erc20.sol new file mode 100644 index 00000000..0e0759d6 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_erc20/erc20.sol @@ -0,0 +1,148 @@ +pragma abicoder v2; +// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value +// types. + +// User defined type name. Indicating a type with 18 decimals. +type UFixed18 is uint256; + +library FixedMath +{ + function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) { + return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b)); + } + function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) { + return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b)); + } +} + +contract ERC20 { + using FixedMath for UFixed18; + + event Transfer(address indexed from, address indexed to, UFixed18 value); + event Approval(address indexed owner, address indexed spender, UFixed18 value); + + mapping (address => UFixed18) private _balances; + mapping (address => mapping (address => UFixed18)) private _allowances; + UFixed18 private _totalSupply; + + constructor() { + _mint(msg.sender, UFixed18.wrap(20)); + } + + function totalSupply() public view returns (UFixed18) { + return _totalSupply; + } + + function balanceOf(address owner) public view returns (UFixed18) { + return _balances[owner]; + } + + function allowance(address owner, address spender) public view returns (UFixed18) { + return _allowances[owner][spender]; + } + + function transfer(address to, UFixed18 value) public returns (bool) { + _transfer(msg.sender, to, value); + return true; + } + + function approve(address spender, UFixed18 value) public returns (bool) { + _approve(msg.sender, spender, value); + return true; + } + + function transferFrom(address from, address to, UFixed18 value) public returns (bool) { + _transfer(from, to, value); + // The subtraction here will revert on overflow. + _approve(from, msg.sender, _allowances[from][msg.sender].sub(value)); + return true; + } + + function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) { + // The addition here will revert on overflow. + _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); + return true; + } + + function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) { + // The subtraction here will revert on overflow. + _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue)); + return true; + } + + function _transfer(address from, address to, UFixed18 value) internal { + require(to != address(0), "ERC20: transfer to the zero address"); + + // The subtraction and addition here will revert on overflow. + _balances[from] = _balances[from].sub(value); + _balances[to] = _balances[to].add(value); + emit Transfer(from, to, value); + } + + function _mint(address account, UFixed18 value) internal { + require(account != address(0), "ERC20: mint to the zero address"); + + // The additions here will revert on overflow. + _totalSupply = _totalSupply.add(value); + _balances[account] = _balances[account].add(value); + emit Transfer(address(0), account, value); + } + + function _burn(address account, UFixed18 value) internal { + require(account != address(0), "ERC20: burn from the zero address"); + + // The subtractions here will revert on overflow. + _totalSupply = _totalSupply.sub(value); + _balances[account] = _balances[account].sub(value); + emit Transfer(account, address(0), value); + } + + function _approve(address owner, address spender, UFixed18 value) internal { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = value; + emit Approval(owner, spender, value); + } + + function _burnFrom(address account, UFixed18 value) internal { + _burn(account, value); + _approve(account, msg.sender, _allowances[account][msg.sender].sub(value)); + } +} +// ---- +// constructor() +// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 +// gas irOptimized: 121322 +// gas irOptimized code: 234600 +// gas legacy: 163350 +// gas legacy code: 671400 +// gas legacyOptimized: 127464 +// gas legacyOptimized code: 285400 +// totalSupply() -> 20 +// gas irOptimized: 23415 +// gas legacy: 23653 +// gas legacyOptimized: 23368 +// transfer(address,uint256): 2, 5 -> true +// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 +// gas irOptimized: 48471 +// gas legacy: 49572 +// gas legacyOptimized: 48575 +// decreaseAllowance(address,uint256): 2, 0 -> true +// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 +// gas irOptimized: 26275 +// gas legacy: 27204 +// gas legacyOptimized: 26317 +// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 +// gas irOptimized: 24042 +// gas legacy: 24506 +// gas legacyOptimized: 24077 +// transfer(address,uint256): 2, 14 -> true +// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e +// gas irOptimized: 28571 +// gas legacy: 29672 +// gas legacyOptimized: 28675 +// transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 +// gas irOptimized: 24071 +// gas legacy: 24492 +// gas legacyOptimized: 24074 diff --git a/examples/test/semanticTests/userDefinedValueType_erc20/erc20_standard_input.json b/examples/test/semanticTests/userDefinedValueType_erc20/erc20_standard_input.json new file mode 100644 index 00000000..7ab05ea6 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_erc20/erc20_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint.sol b/examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint.sol new file mode 100644 index 00000000..4afd4808 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint.sol @@ -0,0 +1,54 @@ +// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type. +type UFixed256x18 is uint256; + +/// A minimal library to do fixed point operations on UFixed256x18. +library FixedMath { + uint constant multiplier = 10**18; + /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on + /// uint256. + function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) { + return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b)); + } + /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on + /// uint256. + function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) { + return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b); + } + /// Take the floor of a UFixed256x18 number. + /// @return the largest integer that does not exceed `a`. + function floor(UFixed256x18 a) internal returns (uint256) { + return UFixed256x18.unwrap(a) / multiplier; + } + /// Turns a uint256 into a UFixed256x18 of the same value. + /// Reverts if the integer is too large. + function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) { + return UFixed256x18.wrap(a * multiplier); + } +} + +contract TestFixedMath { + function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) { + return FixedMath.add(a, b); + } + function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) { + return FixedMath.mul(a, b); + } + function floor(UFixed256x18 a) external returns (uint256) { + return FixedMath.floor(a); + } + function toUFixed256x18(uint256 a) external returns (UFixed256x18) { + return FixedMath.toUFixed256x18(a); + } +} +// ---- +// add(uint256,uint256): 0, 0 -> 0 +// add(uint256,uint256): 25, 45 -> 0x46 +// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex"4e487b71", 0x11 +// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex"4e487b71", 0x11 +// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120 +// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457 +// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457 +// toUFixed256x18(uint256): 0 -> 0 +// toUFixed256x18(uint256): 5 -> 5000000000000000000 +// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000 +// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint_standard_input.json b/examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint_standard_input.json new file mode 100644 index 00000000..443e0688 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_fixedpoint/fixedpoint_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed.sol b/examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed.sol new file mode 100644 index 00000000..ec017a98 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed.sol @@ -0,0 +1,19 @@ +type MyInt is int16; +type MyBytes is bytes2; +contract C { + MyInt immutable a = MyInt.wrap(-2); + MyBytes immutable b = MyBytes.wrap("ab"); + function() internal returns (uint) immutable f = g; + function direct() view external returns (MyInt, MyBytes) { + return (a, b); + } + function viaasm() view external returns (bytes32 x, bytes32 y) { + MyInt _a = a; + MyBytes _b = b; + assembly { x := _a y := _b } + } + function g() internal pure returns (uint) { return 2; } +} +// ---- +// direct() -> -2, 0x6162000000000000000000000000000000000000000000000000000000000000 +// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed_standard_input.json b/examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed_standard_input.json new file mode 100644 index 00000000..8dbb3cd4 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_immutable_signed/immutable_signed_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "assembly_access_bytes2_abicoder_v1.sol": { + "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "in_parenthesis.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() public returns (MyInt a, int b) {\n (MyInt).wrap;\n a = (MyInt).wrap(5);\n (MyInt).unwrap;\n b = (MyInt).unwrap((MyInt).wrap(10));\n }\n}\n// ----\n// f() -> 5, 10\n" + }, + "multisource_module.sol": { + "content": "==== Source: s1.sol ====\ntype MyInt is int;\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\ncontract C {\n function f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); }\n function g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// g(int256): 1 -> 1\n" + }, + "multisource.sol": { + "content": "==== Source: A ====\ntype MyInt is int;\ntype MyAddress is address;\n==== Source: B ====\nimport {MyInt, MyAddress as OurAddress} from \"A\";\ncontract A {\n function f(int x) external view returns(MyInt) { return MyInt.wrap(x); }\n function f(address x) external view returns(OurAddress) { return OurAddress.wrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// f(address): 1 -> 1\n" + }, + "immutable_signed.sol": { + "content": "type MyInt is int16;\ntype MyBytes is bytes2;\ncontract C {\n MyInt immutable a = MyInt.wrap(-2);\n MyBytes immutable b = MyBytes.wrap(\"ab\");\n function() internal returns (uint) immutable f = g;\n function direct() view external returns (MyInt, MyBytes) {\n return (a, b);\n }\n function viaasm() view external returns (bytes32 x, bytes32 y) {\n MyInt _a = a;\n MyBytes _b = b;\n assembly { x := _a y := _b }\n }\n function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// direct() -> -2, 0x6162000000000000000000000000000000000000000000000000000000000000\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis.sol b/examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis.sol new file mode 100644 index 00000000..1b64dbce --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis.sol @@ -0,0 +1,11 @@ +type MyInt is int; +contract C { + function f() public returns (MyInt a, int b) { + (MyInt).wrap; + a = (MyInt).wrap(5); + (MyInt).unwrap; + b = (MyInt).unwrap((MyInt).wrap(10)); + } +} +// ---- +// f() -> 5, 10 diff --git a/examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis_standard_input.json b/examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis_standard_input.json new file mode 100644 index 00000000..77446926 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_in_parenthesis/in_parenthesis_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "assembly_access_bytes2_abicoder_v1.sol": { + "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "in_parenthesis.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() public returns (MyInt a, int b) {\n (MyInt).wrap;\n a = (MyInt).wrap(5);\n (MyInt).unwrap;\n b = (MyInt).unwrap((MyInt).wrap(10));\n }\n}\n// ----\n// f() -> 5, 10\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key.sol b/examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key.sol new file mode 100644 index 00000000..f209c7a4 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key.sol @@ -0,0 +1,16 @@ +type MyInt is int; +contract C { + mapping(MyInt => int) public m; + function set(MyInt key, int value) external { + m[key] = value; + } + function set_unwrapped(int key, int value) external { + m[MyInt.wrap(key)] = value; + } +} +// ---- +// set(int256,int256): 1, 1 -> +// m(int256): 1 -> 1 +// set_unwrapped(int256,int256): 1, 2 -> +// m(int256): 1 -> 2 +// m(int256): 2 -> 0 diff --git a/examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key_standard_input.json b/examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key_standard_input.json new file mode 100644 index 00000000..e2c680fc --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_mapping_key/mapping_key_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage.sol b/examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage.sol new file mode 100644 index 00000000..db745dce --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage.sol @@ -0,0 +1,41 @@ +pragma abicoder v2; + +type Small is uint16; +type Left is bytes2; +struct S { uint8 a; Small b; Left c; uint8 d; } + +contract C { + S public s; + Small[] public small; + Left[] public l; + function f(S memory _s) public { + s = _s; + } + function g(Small[] memory _small) public returns (Small[] memory) { + small = _small; + return small; + } + function h(Left[] memory _left) public returns (Left[] memory) { + l = _left; + return l; + } +} +// ---- +// s() -> 0, 0, 0x00, 0 +// f((uint8,uint16,bytes2,uint8)): 1, 0xff, "ab", 15 -> +// gas irOptimized: 44473 +// gas legacy: 46213 +// gas legacyOptimized: 44671 +// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15 +// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3 +// gas irOptimized: 69555 +// gas legacy: 76557 +// gas legacyOptimized: 74834 +// small(uint256): 0 -> 1 +// small(uint256): 1 -> 2 +// h(bytes2[]): 0x20, 3, "ab", "cd", "ef" -> 0x20, 3, "ab", "cd", "ef" +// gas irOptimized: 69617 +// gas legacy: 76238 +// gas legacyOptimized: 74921 +// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000 +// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage_standard_input.json b/examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage_standard_input.json new file mode 100644 index 00000000..43e9ad58 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_memory_to_storage/memory_to_storage_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_multisource/multisource.sol b/examples/test/semanticTests/userDefinedValueType_multisource/multisource.sol new file mode 100644 index 00000000..d30c7360 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_multisource/multisource.sol @@ -0,0 +1,12 @@ +==== Source: A ==== +type MyInt is int; +type MyAddress is address; +==== Source: B ==== +import {MyInt, MyAddress as OurAddress} from "A"; +contract A { + function f(int x) external view returns(MyInt) { return MyInt.wrap(x); } + function f(address x) external view returns(OurAddress) { return OurAddress.wrap(x); } +} +// ---- +// f(int256): 5 -> 5 +// f(address): 1 -> 1 diff --git a/examples/test/semanticTests/userDefinedValueType_multisource/multisource_standard_input.json b/examples/test/semanticTests/userDefinedValueType_multisource/multisource_standard_input.json new file mode 100644 index 00000000..e05ea6f0 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_multisource/multisource_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "assembly_access_bytes2_abicoder_v1.sol": { + "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "in_parenthesis.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() public returns (MyInt a, int b) {\n (MyInt).wrap;\n a = (MyInt).wrap(5);\n (MyInt).unwrap;\n b = (MyInt).unwrap((MyInt).wrap(10));\n }\n}\n// ----\n// f() -> 5, 10\n" + }, + "multisource_module.sol": { + "content": "==== Source: s1.sol ====\ntype MyInt is int;\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\ncontract C {\n function f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); }\n function g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// g(int256): 1 -> 1\n" + }, + "multisource.sol": { + "content": "==== Source: A ====\ntype MyInt is int;\ntype MyAddress is address;\n==== Source: B ====\nimport {MyInt, MyAddress as OurAddress} from \"A\";\ncontract A {\n function f(int x) external view returns(MyInt) { return MyInt.wrap(x); }\n function f(address x) external view returns(OurAddress) { return OurAddress.wrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// f(address): 1 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module.sol b/examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module.sol new file mode 100644 index 00000000..5f107ce1 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module.sol @@ -0,0 +1,11 @@ +==== Source: s1.sol ==== +type MyInt is int; +==== Source: s2.sol ==== +import "s1.sol" as M; +contract C { + function f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); } + function g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); } +} +// ---- +// f(int256): 5 -> 5 +// g(int256): 1 -> 1 diff --git a/examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module_standard_input.json b/examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module_standard_input.json new file mode 100644 index 00000000..f221e1c9 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_multisource_module/multisource_module_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "assembly_access_bytes2_abicoder_v1.sol": { + "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "in_parenthesis.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() public returns (MyInt a, int b) {\n (MyInt).wrap;\n a = (MyInt).wrap(5);\n (MyInt).unwrap;\n b = (MyInt).unwrap((MyInt).wrap(10));\n }\n}\n// ----\n// f() -> 5, 10\n" + }, + "multisource_module.sol": { + "content": "==== Source: s1.sol ====\ntype MyInt is int;\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\ncontract C {\n function f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); }\n function g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// g(int256): 1 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_ownable/ownable.sol b/examples/test/semanticTests/userDefinedValueType_ownable/ownable.sol new file mode 100644 index 00000000..3c9787fd --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_ownable/ownable.sol @@ -0,0 +1,30 @@ +// Implementation of OpenZepplin's +// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol +// using user defined value types. + +contract Ownable { + type Owner is address; + Owner public owner = Owner.wrap(msg.sender); + error OnlyOwner(); + modifier onlyOwner() { + if (Owner.unwrap(owner) != msg.sender) + revert OnlyOwner(); + + _; + } + event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner); + function setOwner(Owner newOwner) onlyOwner external { + emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner}); + owner = newOwner; + } + function renounceOwnership() onlyOwner external { + owner = Owner.wrap(address(0)); + } +} +// ---- +// owner() -> 0x1212121212121212121212121212120000000012 +// setOwner(address): 0x1212121212121212121212121212120000000012 -> +// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012 +// renounceOwnership() -> +// owner() -> 0 +// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex"5fc483c5" diff --git a/examples/test/semanticTests/userDefinedValueType_ownable/ownable_standard_input.json b/examples/test/semanticTests/userDefinedValueType_ownable/ownable_standard_input.json new file mode 100644 index 00000000..3ad9d02d --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_ownable/ownable_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_parameter/parameter.sol b/examples/test/semanticTests/userDefinedValueType_parameter/parameter.sol new file mode 100644 index 00000000..bbabc1dd --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_parameter/parameter.sol @@ -0,0 +1,40 @@ +pragma abicoder v2; + +type MyAddress is address; +contract C { + function id(MyAddress a) external returns (MyAddress b) { + b = a; + } + + function unwrap_assembly(MyAddress a) external returns (address b) { + assembly { b := a } + } + + function wrap_assembly(address a) external returns (MyAddress b) { + assembly { b := a } + } + + function unwrap(MyAddress a) external returns (address b) { + b = MyAddress.unwrap(a); + } + function wrap(address a) external returns (MyAddress b) { + b = MyAddress.wrap(a); + } + +} +// ---- +// id(address): 5 -> 5 +// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE +// unwrap(address): 5 -> 5 +// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE +// wrap(address): 5 -> 5 +// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE +// unwrap_assembly(address): 5 -> 5 +// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE +// wrap_assembly(address): 5 -> 5 +// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff +// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE diff --git a/examples/test/semanticTests/userDefinedValueType_parameter/parameter_standard_input.json b/examples/test/semanticTests/userDefinedValueType_parameter/parameter_standard_input.json new file mode 100644 index 00000000..cae9b2e6 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_parameter/parameter_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_simple/simple.sol b/examples/test/semanticTests/userDefinedValueType_simple/simple.sol new file mode 100644 index 00000000..e2c23c4f --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_simple/simple.sol @@ -0,0 +1,12 @@ +type MyInt is int; +contract C { + function f() external pure returns (MyInt a) { + } + function g() external pure returns (MyInt b, MyInt c) { + b = MyInt.wrap(int(1)); + c = MyInt.wrap(1); + } +} +// ---- +// f() -> 0 +// g() -> 1, 1 diff --git a/examples/test/semanticTests/userDefinedValueType_simple/simple_standard_input.json b/examples/test/semanticTests/userDefinedValueType_simple/simple_standard_input.json new file mode 100644 index 00000000..a5d8e33a --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_simple/simple_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout.sol b/examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout.sol new file mode 100644 index 00000000..284b4122 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout.sol @@ -0,0 +1,72 @@ +type MyInt8 is int8; +type MyAddress is address; +type MyInt96 is int96; + +contract C { + MyInt8 a; + MyInt8 b; + MyInt8 c; + MyAddress d; + + MyAddress e; + + MyAddress f; + MyInt96 g; + + function storage_a() pure external returns(uint slot, uint offset) { + assembly { + slot := a.slot + offset := a.offset + } + } + + function storage_b() pure external returns(uint slot, uint offset) { + assembly { + slot := b.slot + offset := b.offset + } + } + + function storage_c() pure external returns(uint slot, uint offset) { + assembly { + slot := d.slot + offset := c.offset + } + } + function storage_d() pure external returns(uint slot, uint offset) { + assembly { + slot := d.slot + offset := d.offset + } + } + + function storage_e() pure external returns(uint slot, uint offset) { + assembly { + slot := e.slot + offset := e.offset + } + } + + function storage_f() pure external returns(uint slot, uint offset) { + assembly { + slot := f.slot + offset := f.offset + } + } + + function storage_g() pure external returns(uint slot, uint offset) { + assembly { + slot := g.slot + offset := g.offset + } + } + +} +// ---- +// storage_a() -> 0, 0 +// storage_b() -> 0, 1 +// storage_c() -> 0, 2 +// storage_d() -> 0, 3 +// storage_e() -> 1, 0 +// storage_f() -> 2, 0 +// storage_g() -> 2, 0x14 diff --git a/examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout_standard_input.json b/examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout_standard_input.json new file mode 100644 index 00000000..682c4208 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_storage_layout/storage_layout_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct.sol b/examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct.sol new file mode 100644 index 00000000..8c51b292 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct.sol @@ -0,0 +1,178 @@ +type MyInt64 is int64; +struct HalfSlot { + MyInt64 a; + MyInt64 b; +} + +struct RegularHalfSlot { + int64 a; + int64 b; +} + +type MyAddress is address; +type MyInt96 is int96; +struct FullSlot { + MyInt96 a; + MyAddress b; +} +struct RegularFullSlot { + int96 a; + address b; +} + +contract C { + HalfSlot public a; + RegularHalfSlot public ra; + + HalfSlot public b; + RegularHalfSlot public rb; + + HalfSlot public c; + RegularHalfSlot public rc; + + FullSlot public d; + RegularFullSlot public rd; + + function storage_a() pure external returns(uint slot, uint offset) { + assembly { + slot := a.slot + offset := a.offset + } + } + + function storage_ra() pure external returns(uint slot, uint offset) { + assembly { + slot := ra.slot + offset := ra.offset + } + } + + function storage_b() pure external returns(uint slot, uint offset) { + assembly { + slot := b.slot + offset := b.offset + } + } + + function storage_rb() pure external returns(uint slot, uint offset) { + assembly { + slot := rb.slot + offset := rb.offset + } + } + + function storage_c() pure external returns(uint slot, uint offset) { + assembly { + slot := c.slot + offset := c.offset + } + } + + function storage_rc() pure external returns(uint slot, uint offset) { + assembly { + slot := rc.slot + offset := rc.offset + } + } + + function storage_d() pure external returns(uint slot, uint offset) { + assembly { + slot := d.slot + offset := d.offset + } + } + + function storage_rd() pure external returns(uint slot, uint offset) { + assembly { + slot := rd.slot + offset := rd.offset + } + } + + + function set_a(MyInt64 _a, MyInt64 _b) external { + a.a = _a; + a.b = _b; + } + + function set_ra(int64 _a, int64 _b) external { + ra.a = _a; + ra.b = _b; + } + + function set_b(MyInt64 _a, MyInt64 _b) external { + b.a = _a; + b.b = _b; + } + + function set_rb(int64 _a, int64 _b) external { + rb.a = _a; + rb.b = _b; + } + + function set_c(MyInt64 _a, MyInt64 _b) external { + c.a = _a; + c.b = _b; + } + + function set_rc(int64 _a, int64 _b) external { + rc.a = _a; + rc.b = _b; + } + + function set_d(MyInt96 _a, MyAddress _b) external { + d.a = _a; + d.b = _b; + } + + function set_rd(int96 _a, address _b) external { + rd.a = _a; + rd.b = _b; + } + + function read_slot(uint slot) view external returns (uint value) { + assembly { + value := sload(slot) + } + } + + function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) { + b.a = MyInt64.wrap(-2); + b.b = MyInt64.wrap(-3); + HalfSlot memory x = b; + MyInt64 y = b.a; + MyInt64 z = b.b; + assembly { + rxa := mload(x) + rya := y + rxb := mload(add(x, 0x20)) + ryb := z + } + } +} +// ---- +// storage_a() -> 0, 0 +// set_a(int64,int64): 100, 200 -> +// read_slot(uint256): 0 -> 0xc80000000000000064 +// storage_ra() -> 1, 0 +// set_ra(int64,int64): 100, 200 -> +// read_slot(uint256): 1 -> 0xc80000000000000064 +// storage_b() -> 2, 0 +// set_b(int64,int64): 0, 200 -> +// read_slot(uint256): 2 -> 3689348814741910323200 +// storage_rb() -> 3, 0 +// set_rb(int64,int64): 0, 200 -> +// read_slot(uint256): 3 -> 3689348814741910323200 +// storage_c() -> 4, 0 +// set_c(int64,int64): 100, 0 -> +// read_slot(uint256): 4 -> 0x64 +// storage_rc() -> 5, 0 +// set_rc(int64,int64): 100, 0 -> +// read_slot(uint256): 5 -> 0x64 +// storage_d() -> 6, 0 +// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 -> +// read_slot(uint256): 6 -> -39614081257132168796771975169 +// storage_rd() -> 7, 0 +// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 -> +// read_slot(uint256): 7 -> -39614081257132168796771975169 +// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd diff --git a/examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct_standard_input.json b/examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct_standard_input.json new file mode 100644 index 00000000..884ae5da --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_storage_layout_struct/storage_layout_struct_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed.sol b/examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed.sol new file mode 100644 index 00000000..813931e0 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed.sol @@ -0,0 +1,33 @@ +type MyInt is int16; +contract C { + bytes2 first = "ab"; + MyInt public a = MyInt.wrap(-2); + bytes2 third = "ef"; + function direct() external returns (MyInt) { + return a; + } + function indirect() external returns (int16) { + return MyInt.unwrap(a); + } + function toMemDirect() external returns (MyInt[1] memory) { + return [a]; + } + function toMemIndirect() external returns (int16[1] memory) { + return [MyInt.unwrap(a)]; + } + function div() external returns (int16) { + return MyInt.unwrap(a) / 2; + } + function viaasm() external returns (bytes32 x) { + MyInt st = a; + assembly { x := st } + } +} +// ---- +// a() -> -2 +// direct() -> -2 +// indirect() -> -2 +// toMemDirect() -> -2 +// toMemIndirect() -> -2 +// div() -> -1 +// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe diff --git a/examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed_standard_input.json b/examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed_standard_input.json new file mode 100644 index 00000000..4895dcf1 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_storage_signed/storage_signed_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap.sol b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap.sol new file mode 100644 index 00000000..117e0dd8 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap.sol @@ -0,0 +1,9 @@ +type MyAddress is address; +contract C { + function f() pure public { + MyAddress.wrap; + MyAddress.unwrap; + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap_standard_input.json b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap_standard_input.json new file mode 100644 index 00000000..b9c986d5 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap/wrap_unwrap_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name.sol b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name.sol new file mode 100644 index 00000000..1da734fa --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name.sol @@ -0,0 +1,22 @@ +contract C { + type T is uint; +} +contract D { + function f(C.T x) public pure returns(uint) { + return C.T.unwrap(x); + } + function g(uint x) public pure returns(C.T) { + return C.T.wrap(x); + } + function h(uint x) public pure returns(uint) { + return f(g(x)); + } + function i(C.T x) public pure returns(C.T) { + return g(f(x)); + } +} +// ---- +// f(uint256): 0x42 -> 0x42 +// g(uint256): 0x42 -> 0x42 +// h(uint256): 0x42 -> 0x42 +// i(uint256): 0x42 -> 0x42 diff --git a/examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name_standard_input.json b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name_standard_input.json new file mode 100644 index 00000000..d284d082 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_wrap_unwrap_via_contract_name/wrap_unwrap_via_contract_name_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + }, + "constant.sol": { + "content": "type T is int224;\npragma solidity >= 0.0.0;\ncontract C {\n T constant public s = T.wrap(int224(165521356710917456517261742455526507355687727119203895813322792776));\n T constant public t = s;\n int224 constant public u = T.unwrap(t);\n}\n// ----\n// s() -> 165521356710917456517261742455526507355687727119203895813322792776\n// t() -> 165521356710917456517261742455526507355687727119203895813322792776\n// u() -> 165521356710917456517261742455526507355687727119203895813322792776\n" + }, + "storage_layout_struct.sol": { + "content": "type MyInt64 is int64;\nstruct HalfSlot {\n MyInt64 a;\n MyInt64 b;\n}\n\nstruct RegularHalfSlot {\n int64 a;\n int64 b;\n}\n\ntype MyAddress is address;\ntype MyInt96 is int96;\nstruct FullSlot {\n MyInt96 a;\n MyAddress b;\n}\nstruct RegularFullSlot {\n int96 a;\n address b;\n}\n\ncontract C {\n HalfSlot public a;\n RegularHalfSlot public ra;\n\n HalfSlot public b;\n RegularHalfSlot public rb;\n\n HalfSlot public c;\n RegularHalfSlot public rc;\n\n FullSlot public d;\n RegularFullSlot public rd;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_ra() pure external returns(uint slot, uint offset) {\n assembly {\n slot := ra.slot\n offset := ra.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_rb() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rb.slot\n offset := rb.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := c.slot\n offset := c.offset\n }\n }\n\n function storage_rc() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rc.slot\n offset := rc.offset\n }\n }\n\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_rd() pure external returns(uint slot, uint offset) {\n assembly {\n slot := rd.slot\n offset := rd.offset\n }\n }\n\n\n function set_a(MyInt64 _a, MyInt64 _b) external {\n a.a = _a;\n a.b = _b;\n }\n\n function set_ra(int64 _a, int64 _b) external {\n ra.a = _a;\n ra.b = _b;\n }\n\n function set_b(MyInt64 _a, MyInt64 _b) external {\n b.a = _a;\n b.b = _b;\n }\n\n function set_rb(int64 _a, int64 _b) external {\n rb.a = _a;\n rb.b = _b;\n }\n\n function set_c(MyInt64 _a, MyInt64 _b) external {\n c.a = _a;\n c.b = _b;\n }\n\n function set_rc(int64 _a, int64 _b) external {\n rc.a = _a;\n rc.b = _b;\n }\n\n function set_d(MyInt96 _a, MyAddress _b) external {\n d.a = _a;\n d.b = _b;\n }\n\n function set_rd(int96 _a, address _b) external {\n rd.a = _a;\n rd.b = _b;\n }\n\n function read_slot(uint slot) view external returns (uint value) {\n assembly {\n value := sload(slot)\n }\n }\n\n function read_contents_asm() external returns (bytes32 rxa, bytes32 rya, bytes32 rxb, bytes32 ryb) {\n b.a = MyInt64.wrap(-2);\n b.b = MyInt64.wrap(-3);\n HalfSlot memory x = b;\n MyInt64 y = b.a;\n MyInt64 z = b.b;\n assembly {\n rxa := mload(x)\n rya := y\n rxb := mload(add(x, 0x20))\n ryb := z\n }\n }\n}\n// ----\n// storage_a() -> 0, 0\n// set_a(int64,int64): 100, 200 ->\n// read_slot(uint256): 0 -> 0xc80000000000000064\n// storage_ra() -> 1, 0\n// set_ra(int64,int64): 100, 200 ->\n// read_slot(uint256): 1 -> 0xc80000000000000064\n// storage_b() -> 2, 0\n// set_b(int64,int64): 0, 200 ->\n// read_slot(uint256): 2 -> 3689348814741910323200\n// storage_rb() -> 3, 0\n// set_rb(int64,int64): 0, 200 ->\n// read_slot(uint256): 3 -> 3689348814741910323200\n// storage_c() -> 4, 0\n// set_c(int64,int64): 100, 0 ->\n// read_slot(uint256): 4 -> 0x64\n// storage_rc() -> 5, 0\n// set_rc(int64,int64): 100, 0 ->\n// read_slot(uint256): 5 -> 0x64\n// storage_d() -> 6, 0\n// set_d(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 6 -> -39614081257132168796771975169\n// storage_rd() -> 7, 0\n// set_rd(int96,address): 39614081257132168796771975167, 1461501637330902918203684832716283019655932542975 ->\n// read_slot(uint256): 7 -> -39614081257132168796771975169\n// read_contents_asm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd\n" + }, + "erc20.sol": { + "content": "pragma abicoder v2;\n// A rewrite of the test/libsolidity/semanticTests/various/erc20.sol, but using user defined value\n// types.\n\n// User defined type name. Indicating a type with 18 decimals.\ntype UFixed18 is uint256;\n\nlibrary FixedMath\n{\n function add(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) + UFixed18.unwrap(b));\n }\n function sub(UFixed18 a, UFixed18 b) internal pure returns (UFixed18 c) {\n return UFixed18.wrap(UFixed18.unwrap(a) - UFixed18.unwrap(b));\n }\n}\n\ncontract ERC20 {\n using FixedMath for UFixed18;\n\n event Transfer(address indexed from, address indexed to, UFixed18 value);\n event Approval(address indexed owner, address indexed spender, UFixed18 value);\n\n mapping (address => UFixed18) private _balances;\n mapping (address => mapping (address => UFixed18)) private _allowances;\n UFixed18 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, UFixed18.wrap(20));\n }\n\n function totalSupply() public view returns (UFixed18) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (UFixed18) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (UFixed18) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, UFixed18 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, UFixed18 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, UFixed18 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender].sub(value));\n return true;\n }\n\n function increaseAllowance(address spender, UFixed18 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));\n return true;\n }\n\n function decreaseAllowance(address spender, UFixed18 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));\n return true;\n }\n\n function _transfer(address from, address to, UFixed18 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, UFixed18 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, UFixed18 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, UFixed18 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender].sub(value));\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121322\n// gas irOptimized code: 234600\n// gas legacy: 163350\n// gas legacy code: 671400\n// gas legacyOptimized: 127464\n// gas legacyOptimized code: 285400\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23653\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49572\n// gas legacyOptimized: 48575\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27204\n// gas legacyOptimized: 26317\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24506\n// gas legacyOptimized: 24077\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29672\n// gas legacyOptimized: 28675\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24492\n// gas legacyOptimized: 24074\n" + }, + "conversion.sol": { + "content": "pragma abicoder v2;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> FAILURE\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> FAILURE\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> FAILURE\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "dirty_uint8_read.sol": { + "content": "type MyInt8 is int8;\ncontract C {\n MyInt8 public x = MyInt8.wrap(-5);\n\n /// The most significant bit is flipped to 0\n function create_dirty_slot() external {\n uint mask = 2**255 -1;\n assembly {\n let value := sload(x.slot)\n sstore(x.slot, and(mask, value))\n }\n }\n\n function read_unclean_value() external returns (bytes32 ret) {\n MyInt8 value = x;\n assembly {\n ret := value\n }\n }\n}\n// ----\n// x() -> -5\n// create_dirty_slot() ->\n// read_unclean_value() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb\n" + }, + "ownable.sol": { + "content": "// Implementation of OpenZepplin's\n// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol\n// using user defined value types.\n\ncontract Ownable {\n type Owner is address;\n Owner public owner = Owner.wrap(msg.sender);\n error OnlyOwner();\n modifier onlyOwner() {\n if (Owner.unwrap(owner) != msg.sender)\n revert OnlyOwner();\n\n _;\n }\n event OwnershipTransferred(Owner indexed previousOwner, Owner indexed newOwner);\n function setOwner(Owner newOwner) onlyOwner external {\n emit OwnershipTransferred({previousOwner: owner, newOwner: newOwner});\n owner = newOwner;\n }\n function renounceOwnership() onlyOwner external {\n owner = Owner.wrap(address(0));\n }\n}\n// ----\n// owner() -> 0x1212121212121212121212121212120000000012\n// setOwner(address): 0x1212121212121212121212121212120000000012 ->\n// ~ emit OwnershipTransferred(address,address): #0x1212121212121212121212121212120000000012, #0x1212121212121212121212121212120000000012\n// renounceOwnership() ->\n// owner() -> 0\n// setOwner(address): 0x1212121212121212121212121212120000000012 -> FAILURE, hex\"5fc483c5\"\n" + }, + "conversion_abicoderv1.sol": { + "content": "pragma abicoder v1;\n\ntype MyUInt8 is uint8;\ntype MyInt8 is int8;\ntype MyUInt16 is uint16;\n\ncontract C {\n function f(uint a) external returns(MyUInt8) {\n return MyUInt8.wrap(uint8(a));\n }\n function g(uint a) external returns(MyInt8) {\n return MyInt8.wrap(int8(int(a)));\n }\n function h(MyUInt8 a) external returns (MyInt8) {\n return MyInt8.wrap(int8(MyUInt8.unwrap(a)));\n }\n function i(MyUInt8 a) external returns(MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function j(MyUInt8 a) external returns (uint) {\n return MyUInt8.unwrap(a);\n }\n function k(MyUInt8 a) external returns (MyUInt16) {\n return MyUInt16.wrap(MyUInt8.unwrap(a));\n }\n function m(MyUInt16 a) external returns (MyUInt8) {\n return MyUInt8.wrap(uint8(MyUInt16.unwrap(a)));\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// f(uint256): 1 -> 1\n// f(uint256): 2 -> 2\n// f(uint256): 257 -> 1\n// g(uint256): 1 -> 1\n// g(uint256): 2 -> 2\n// g(uint256): 255 -> -1\n// g(uint256): 257 -> 1\n// h(uint8): 1 -> 1\n// h(uint8): 2 -> 2\n// h(uint8): 255 -> -1\n// h(uint8): 257 -> 1\n// i(uint8): 250 -> 250\n// j(uint8): 1 -> 1\n// j(uint8): 2 -> 2\n// j(uint8): 255 -> 0xff\n// j(uint8): 257 -> 1\n// k(uint8): 1 -> 1\n// k(uint8): 2 -> 2\n// k(uint8): 255 -> 0xff\n// k(uint8): 257 -> 1\n// m(uint16): 1 -> 1\n// m(uint16): 2 -> 2\n// m(uint16): 255 -> 0xff\n// m(uint16): 257 -> 1\n" + }, + "abicodec.sol": { + "content": "// A test to see if `abi.encodeWithSelector(..., (CustomType))` works as intended.\ncontract C {\n type MyInt is int;\n function f(MyInt x) external returns(MyInt a, MyInt b, MyInt c, MyInt d) {\n a = MyInt.wrap(-1);\n b = MyInt.wrap(0);\n c = MyInt.wrap(1);\n d = x;\n }\n function g() external returns(bool) {\n (bool success1, bytes memory ret1) = address(this).call(abi.encodeWithSelector(this.f.selector, MyInt.wrap(5)));\n assert(success1);\n\n (MyInt a1, MyInt b1, MyInt c1, MyInt d1) = abi.decode(ret1, (MyInt, MyInt, MyInt, MyInt));\n assert(MyInt.unwrap(a1) == -1);\n assert(MyInt.unwrap(b1) == 0);\n assert(MyInt.unwrap(c1) == 1);\n assert(MyInt.unwrap(d1) == 5);\n\n (bool success2, bytes memory ret2) = address(this).call(abi.encodeWithSelector(this.f.selector, int(-5)));\n assert(success2);\n\n (int a2, int b2, int c2, int d2) = abi.decode(ret2, (int, int, int, int));\n assert(a2 == -1);\n assert(b2 == 0);\n assert(c2 == 1);\n assert(d2 == -5);\n\n return true;\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// g() -> true\n" + }, + "fixedpoint.sol": { + "content": "// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.\ntype UFixed256x18 is uint256;\n\n/// A minimal library to do fixed point operations on UFixed256x18.\nlibrary FixedMath {\n uint constant multiplier = 10**18;\n /// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function add(UFixed256x18 a, UFixed256x18 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));\n }\n /// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked arithmetic on\n /// uint256.\n function mul(UFixed256x18 a, uint256 b) internal returns (UFixed256x18) {\n return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);\n }\n /// Take the floor of a UFixed256x18 number.\n /// @return the largest integer that does not exceed `a`.\n function floor(UFixed256x18 a) internal returns (uint256) {\n return UFixed256x18.unwrap(a) / multiplier;\n }\n /// Turns a uint256 into a UFixed256x18 of the same value.\n /// Reverts if the integer is too large.\n function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {\n return UFixed256x18.wrap(a * multiplier);\n }\n}\n\ncontract TestFixedMath {\n function add(UFixed256x18 a, UFixed256x18 b) external returns (UFixed256x18) {\n return FixedMath.add(a, b);\n }\n function mul(UFixed256x18 a, uint256 b) external returns (UFixed256x18) {\n return FixedMath.mul(a, b);\n }\n function floor(UFixed256x18 a) external returns (uint256) {\n return FixedMath.floor(a);\n }\n function toUFixed256x18(uint256 a) external returns (UFixed256x18) {\n return FixedMath.toUFixed256x18(a);\n }\n}\n// ----\n// add(uint256,uint256): 0, 0 -> 0\n// add(uint256,uint256): 25, 45 -> 0x46\n// add(uint256,uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 45671926166590716193865151022383844364247891968 -> FAILURE, hex\"4e487b71\", 0x11\n// mul(uint256,uint256): 340282366920938463463374607431768211456, 20 -> 6805647338418769269267492148635364229120\n// floor(uint256): 11579208923731619542357098500868790785326998665640564039457584007913129639930 -> 11579208923731619542357098500868790785326998665640564039457\n// floor(uint256): 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> 115792089237316195423570985008687907853269984665640564039457\n// toUFixed256x18(uint256): 0 -> 0\n// toUFixed256x18(uint256): 5 -> 5000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039457 -> 115792089237316195423570985008687907853269984665640564039457000000000000000000\n// toUFixed256x18(uint256): 115792089237316195423570985008687907853269984665640564039458 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "storage_layout.sol": { + "content": "type MyInt8 is int8;\ntype MyAddress is address;\ntype MyInt96 is int96;\n\ncontract C {\n MyInt8 a;\n MyInt8 b;\n MyInt8 c;\n MyAddress d;\n\n MyAddress e;\n\n MyAddress f;\n MyInt96 g;\n\n function storage_a() pure external returns(uint slot, uint offset) {\n assembly {\n slot := a.slot\n offset := a.offset\n }\n }\n\n function storage_b() pure external returns(uint slot, uint offset) {\n assembly {\n slot := b.slot\n offset := b.offset\n }\n }\n\n function storage_c() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := c.offset\n }\n }\n function storage_d() pure external returns(uint slot, uint offset) {\n assembly {\n slot := d.slot\n offset := d.offset\n }\n }\n\n function storage_e() pure external returns(uint slot, uint offset) {\n assembly {\n slot := e.slot\n offset := e.offset\n }\n }\n\n function storage_f() pure external returns(uint slot, uint offset) {\n assembly {\n slot := f.slot\n offset := f.offset\n }\n }\n\n function storage_g() pure external returns(uint slot, uint offset) {\n assembly {\n slot := g.slot\n offset := g.offset\n }\n }\n\n}\n// ----\n// storage_a() -> 0, 0\n// storage_b() -> 0, 1\n// storage_c() -> 0, 2\n// storage_d() -> 0, 3\n// storage_e() -> 1, 0\n// storage_f() -> 2, 0\n// storage_g() -> 2, 0x14\n" + }, + "mapping_key.sol": { + "content": "type MyInt is int;\ncontract C {\n mapping(MyInt => int) public m;\n function set(MyInt key, int value) external {\n m[key] = value;\n }\n function set_unwrapped(int key, int value) external {\n m[MyInt.wrap(key)] = value;\n }\n}\n// ----\n// set(int256,int256): 1, 1 ->\n// m(int256): 1 -> 1\n// set_unwrapped(int256,int256): 1, 2 ->\n// m(int256): 1 -> 2\n// m(int256): 2 -> 0\n" + }, + "cleanup.sol": { + "content": "pragma abicoder v2;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> FAILURE\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0xff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "memory_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S memory _s) public {\n s = _s;\n }\n function g(Small[] memory _small) public returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] memory _left) public returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44473\n// gas legacy: 46213\n// gas legacyOptimized: 44671\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69555\n// gas legacy: 76557\n// gas legacyOptimized: 74834\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69617\n// gas legacy: 76238\n// gas legacyOptimized: 74921\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "dirty_slot.sol": { + "content": "type MyUInt16 is uint16;\ntype MyBytes2 is bytes2;\ncontract C {\n MyUInt16 public a = MyUInt16.wrap(13);\n MyBytes2 public b = MyBytes2.wrap(bytes2(uint16(1025)));\n bytes2 public x;\n function write_a() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(a.slot, max)\n }\n }\n function write_b() external {\n uint max = 0xf00e0bbc0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e0c0ba098076054032001;\n assembly {\n sstore(b.slot, max)\n }\n }\n function get_b(uint index) public returns (bytes1) {\n return MyBytes2.unwrap(b)[index];\n }\n}\n// ----\n// a() -> 13\n// b() -> 0x0401000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x0400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n// write_a() ->\n// a() -> 0x2001\n// write_b() ->\n// b() -> 0x5403000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 0 -> 0x5400000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 1 -> 0x0300000000000000000000000000000000000000000000000000000000000000\n// get_b(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x32\n" + }, + "calldata_to_storage.sol": { + "content": "pragma abicoder v2;\n\ntype Small is uint16;\ntype Left is bytes2;\nstruct S { uint8 a; Small b; Left c; uint8 d; }\n\ncontract C {\n S public s;\n Small[] public small;\n Left[] public l;\n function f(S calldata _s) external {\n s = _s;\n }\n function g(Small[] calldata _small) external returns (Small[] memory) {\n small = _small;\n return small;\n }\n function h(Left[] calldata _left) external returns (Left[] memory) {\n l = _left;\n return l;\n }\n}\n// ----\n// s() -> 0, 0, 0x00, 0\n// f((uint8,uint16,bytes2,uint8)): 1, 0xff, \"ab\", 15 ->\n// gas irOptimized: 44405\n// gas legacy: 47200\n// gas legacyOptimized: 44923\n// s() -> 1, 0xff, 0x6162000000000000000000000000000000000000000000000000000000000000, 15\n// g(uint16[]): 0x20, 3, 1, 2, 3 -> 0x20, 3, 1, 2, 3\n// gas irOptimized: 69097\n// gas legacy: 75466\n// gas legacyOptimized: 74255\n// small(uint256): 0 -> 1\n// small(uint256): 1 -> 2\n// h(bytes2[]): 0x20, 3, \"ab\", \"cd\", \"ef\" -> 0x20, 3, \"ab\", \"cd\", \"ef\"\n// gas irOptimized: 69174\n// gas legacy: 75156\n// gas legacyOptimized: 74342\n// l(uint256): 0 -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// l(uint256): 1 -> 0x6364000000000000000000000000000000000000000000000000000000000000\n" + }, + "calldata.sol": { + "content": "pragma abicoder v2;\ntype MyAddress is address;\n\ncontract C {\n MyAddress[] public addresses;\n function f(MyAddress[] calldata _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function g(MyAddress[] memory _addresses) external {\n for (uint i = 0; i < _addresses.length; i++) {\n MyAddress.unwrap(_addresses[i]).call(\"\");\n }\n addresses = _addresses;\n }\n function test_f() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](3);\n test[0] = MyAddress.wrap(address(21));\n test[1] = MyAddress.wrap(address(22));\n test[2] = MyAddress.wrap(address(23));\n this.f(test);\n test_equality(test);\n return true;\n }\n function test_g() external returns (bool) {\n clean();\n MyAddress[] memory test = new MyAddress[](5);\n test[0] = MyAddress.wrap(address(24));\n test[1] = MyAddress.wrap(address(25));\n test[2] = MyAddress.wrap(address(26));\n test[3] = MyAddress.wrap(address(27));\n test[4] = MyAddress.wrap(address(28));\n this.g(test);\n test_equality(test);\n return true;\n }\n function clean() internal {\n delete addresses;\n }\n function test_equality(MyAddress[] memory _addresses) internal view {\n require (_addresses.length == addresses.length);\n for (uint i = 0; i < _addresses.length; i++) {\n require(MyAddress.unwrap(_addresses[i]) == MyAddress.unwrap(addresses[i]));\n }\n }\n}\n// ----\n// test_f() -> true\n// gas irOptimized: 122201\n// gas legacy: 125333\n// gas legacyOptimized: 122693\n// test_g() -> true\n// gas irOptimized: 106408\n// gas legacy: 111133\n// gas legacyOptimized: 106925\n// addresses(uint256): 0 -> 0x18\n// addresses(uint256): 1 -> 0x19\n// addresses(uint256): 3 -> 0x1b\n// addresses(uint256): 4 -> 0x1c\n// addresses(uint256): 5 -> FAILURE\n" + }, + "cleanup_abicoderv1.sol": { + "content": "pragma abicoder v1;\ntype MyUInt8 is uint8;\n\n// Note that this wraps from a uint256\nfunction wrap(uint x) pure returns (MyUInt8 y) { assembly { y := x } }\nfunction unwrap(MyUInt8 x) pure returns (uint8 y) { assembly { y := x } }\n\ncontract C {\n uint8 a;\n MyUInt8 b;\n uint8 c;\n function ret() external returns(MyUInt8) {\n return wrap(0x1ff);\n }\n function f(MyUInt8 x) external returns(MyUInt8) {\n return x;\n }\n function mem() external returns (MyUInt8[] memory) {\n MyUInt8[] memory x = new MyUInt8[](2);\n x[0] = wrap(0x1ff);\n x[1] = wrap(0xff);\n require(unwrap(x[0]) == unwrap(x[1]));\n assembly {\n mstore(add(x, 0x20), 0x1ff)\n }\n require(unwrap(x[0]) == unwrap(x[1]));\n return x;\n }\n function stor() external returns (uint8, MyUInt8, uint8) {\n a = 1;\n c = 2;\n b = wrap(0x1ff);\n return (a, b, c);\n }\n}\n// ====\n// compileViaYul: false\n// ----\n// ret() -> 0xff\n// f(uint8): 0x1ff -> 0xff\n// f(uint8): 0xff -> 0xff\n// mem() -> 0x20, 2, 0x01ff, 0xff\n// stor() -> 1, 0xff, 2\n" + }, + "simple.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() external pure returns (MyInt a) {\n }\n function g() external pure returns (MyInt b, MyInt c) {\n b = MyInt.wrap(int(1));\n c = MyInt.wrap(1);\n }\n}\n// ----\n// f() -> 0\n// g() -> 1, 1\n" + }, + "wrap_unwrap.sol": { + "content": "type MyAddress is address;\ncontract C {\n function f() pure public {\n MyAddress.wrap;\n MyAddress.unwrap;\n }\n}\n// ----\n// f() ->\n" + }, + "storage_signed.sol": { + "content": "type MyInt is int16;\ncontract C {\n bytes2 first = \"ab\";\n MyInt public a = MyInt.wrap(-2);\n bytes2 third = \"ef\";\n function direct() external returns (MyInt) {\n return a;\n }\n function indirect() external returns (int16) {\n return MyInt.unwrap(a);\n }\n function toMemDirect() external returns (MyInt[1] memory) {\n return [a];\n }\n function toMemIndirect() external returns (int16[1] memory) {\n return [MyInt.unwrap(a)];\n }\n function div() external returns (int16) {\n return MyInt.unwrap(a) / 2;\n }\n function viaasm() external returns (bytes32 x) {\n MyInt st = a;\n assembly { x := st }\n }\n}\n// ----\n// a() -> -2\n// direct() -> -2\n// indirect() -> -2\n// toMemDirect() -> -2\n// toMemIndirect() -> -2\n// div() -> -1\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe\n" + }, + "assembly_access_bytes2_abicoder_v2.sol": { + "content": "pragma abicoder v2;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> FAILURE\n// g(bytes2): \"abcdef\" -> FAILURE\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "parameter.sol": { + "content": "pragma abicoder v2;\n\ntype MyAddress is address;\ncontract C {\n function id(MyAddress a) external returns (MyAddress b) {\n b = a;\n }\n\n function unwrap_assembly(MyAddress a) external returns (address b) {\n assembly { b := a }\n }\n\n function wrap_assembly(address a) external returns (MyAddress b) {\n assembly { b := a }\n }\n\n function unwrap(MyAddress a) external returns (address b) {\n b = MyAddress.unwrap(a);\n }\n function wrap(address a) external returns (MyAddress b) {\n b = MyAddress.wrap(a);\n }\n\n}\n// ----\n// id(address): 5 -> 5\n// id(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// id(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap(address): 5 -> 5\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap(address): 5 -> 5\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// unwrap_assembly(address): 5 -> 5\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// unwrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n// wrap_assembly(address): 5 -> 5\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffff -> 0xffffffffffffffffffffffffffffffffffffffff\n// wrap_assembly(address): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE\n" + }, + "assembly_access_bytes2_abicoder_v1.sol": { + "content": "pragma abicoder v1;\n\ntype MyBytes2 is bytes2;\n\ncontract C {\n function f(MyBytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function g(bytes2 val) external returns (bytes2 ret) {\n assembly {\n ret := val\n }\n }\n\n function h(uint256 val) external returns (MyBytes2) {\n MyBytes2 ret;\n assembly {\n ret := val\n }\n return ret;\n }\n\n}\n// ====\n// compileViaYul: false\n// ----\n// f(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// f(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// g(bytes2): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"ab\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n// h(uint256): \"abcdef\" -> 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "in_parenthesis.sol": { + "content": "type MyInt is int;\ncontract C {\n function f() public returns (MyInt a, int b) {\n (MyInt).wrap;\n a = (MyInt).wrap(5);\n (MyInt).unwrap;\n b = (MyInt).unwrap((MyInt).wrap(10));\n }\n}\n// ----\n// f() -> 5, 10\n" + }, + "multisource_module.sol": { + "content": "==== Source: s1.sol ====\ntype MyInt is int;\n==== Source: s2.sol ====\nimport \"s1.sol\" as M;\ncontract C {\n function f(int x) public pure returns (M.MyInt) { return M.MyInt.wrap(x); }\n function g(M.MyInt x) public pure returns (int) { return M.MyInt.unwrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// g(int256): 1 -> 1\n" + }, + "multisource.sol": { + "content": "==== Source: A ====\ntype MyInt is int;\ntype MyAddress is address;\n==== Source: B ====\nimport {MyInt, MyAddress as OurAddress} from \"A\";\ncontract A {\n function f(int x) external view returns(MyInt) { return MyInt.wrap(x); }\n function f(address x) external view returns(OurAddress) { return OurAddress.wrap(x); }\n}\n// ----\n// f(int256): 5 -> 5\n// f(address): 1 -> 1\n" + }, + "immutable_signed.sol": { + "content": "type MyInt is int16;\ntype MyBytes is bytes2;\ncontract C {\n MyInt immutable a = MyInt.wrap(-2);\n MyBytes immutable b = MyBytes.wrap(\"ab\");\n function() internal returns (uint) immutable f = g;\n function direct() view external returns (MyInt, MyBytes) {\n return (a, b);\n }\n function viaasm() view external returns (bytes32 x, bytes32 y) {\n MyInt _a = a;\n MyBytes _b = b;\n assembly { x := _a y := _b }\n }\n function g() internal pure returns (uint) { return 2; }\n}\n// ----\n// direct() -> -2, 0x6162000000000000000000000000000000000000000000000000000000000000\n// viaasm() -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6162000000000000000000000000000000000000000000000000000000000000\n" + }, + "wrap_unwrap_via_contract_name.sol": { + "content": "contract C {\n type T is uint;\n}\ncontract D {\n function f(C.T x) public pure returns(uint) {\n return C.T.unwrap(x);\n }\n function g(uint x) public pure returns(C.T) {\n return C.T.wrap(x);\n }\n function h(uint x) public pure returns(uint) {\n return f(g(x));\n }\n function i(C.T x) public pure returns(C.T) {\n return g(f(x));\n }\n}\n// ----\n// f(uint256): 0x42 -> 0x42\n// g(uint256): 0x42 -> 0x42\n// h(uint256): 0x42 -> 0x42\n// i(uint256): 0x42 -> 0x42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary.sol b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary.sol new file mode 100644 index 00000000..2c5a15bb --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary.sol @@ -0,0 +1,34 @@ +// a test to compare the cost between using user defined value types and elementary type. See the +// test zero_cost_abstraction_userdefined.sol for a comparison. + +pragma abicoder v2; + +contract C { + int x; + function setX(int _x) external { + x = _x; + } + function getX() view external returns (int) { + return x; + } + function add(int a, int b) view external returns (int) { + return a + b; + } +} +// ---- +// getX() -> 0 +// gas irOptimized: 23379 +// gas legacy: 23479 +// gas legacyOptimized: 23311 +// setX(int256): 5 -> +// gas irOptimized: 43510 +// gas legacy: 43724 +// gas legacyOptimized: 43516 +// getX() -> 5 +// gas irOptimized: 23379 +// gas legacy: 23479 +// gas legacyOptimized: 23311 +// add(int256,int256): 200, 99 -> 299 +// gas irOptimized: 21764 +// gas legacy: 22394 +// gas legacyOptimized: 21813 diff --git a/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary_standard_input.json b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary_standard_input.json new file mode 100644 index 00000000..b48e0e2c --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_elementary/zero_cost_abstraction_comparison_elementary_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + }, + "zero_cost_abstraction_comparison_elementary.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_userdefined.sol for a comparison.\n\npragma abicoder v2;\n\ncontract C {\n int x;\n function setX(int _x) external {\n x = _x;\n }\n function getX() view external returns (int) {\n return x;\n }\n function add(int a, int b) view external returns (int) {\n return a + b;\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23479\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22394\n// gas legacyOptimized: 21813\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined.sol b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined.sol new file mode 100644 index 00000000..2f275c54 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined.sol @@ -0,0 +1,35 @@ +// a test to compare the cost between using user defined value types and elementary type. See the +// test zero_cost_abstraction_elementary.sol for comparison. + +pragma abicoder v2; + +type MyInt is int; +contract C { + int x; + function setX(MyInt _x) external { + x = MyInt.unwrap(_x); + } + function getX() view external returns (MyInt) { + return MyInt.wrap(x); + } + function add(MyInt a, MyInt b) pure external returns(MyInt) { + return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b)); + } +} +// ---- +// getX() -> 0 +// gas irOptimized: 23379 +// gas legacy: 23608 +// gas legacyOptimized: 23311 +// setX(int256): 5 -> +// gas irOptimized: 43510 +// gas legacy: 43724 +// gas legacyOptimized: 43516 +// getX() -> 5 +// gas irOptimized: 23379 +// gas legacy: 23608 +// gas legacyOptimized: 23311 +// add(int256,int256): 200, 99 -> 299 +// gas irOptimized: 21764 +// gas legacy: 22523 +// gas legacyOptimized: 21813 diff --git a/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined_standard_input.json b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined_standard_input.json new file mode 100644 index 00000000..7d795032 --- /dev/null +++ b/examples/test/semanticTests/userDefinedValueType_zero_cost_abstraction_comparison_userdefined/zero_cost_abstraction_comparison_userdefined_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "zero_cost_abstraction_comparison_userdefined.sol": { + "content": "// a test to compare the cost between using user defined value types and elementary type. See the\n// test zero_cost_abstraction_elementary.sol for comparison.\n\npragma abicoder v2;\n\ntype MyInt is int;\ncontract C {\n int x;\n function setX(MyInt _x) external {\n x = MyInt.unwrap(_x);\n }\n function getX() view external returns (MyInt) {\n return MyInt.wrap(x);\n }\n function add(MyInt a, MyInt b) pure external returns(MyInt) {\n return MyInt.wrap(MyInt.unwrap(a) + MyInt.unwrap(b));\n }\n}\n// ----\n// getX() -> 0\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// setX(int256): 5 ->\n// gas irOptimized: 43510\n// gas legacy: 43724\n// gas legacyOptimized: 43516\n// getX() -> 5\n// gas irOptimized: 23379\n// gas legacy: 23608\n// gas legacyOptimized: 23311\n// add(int256,int256): 200, 99 -> 299\n// gas irOptimized: 21764\n// gas legacy: 22523\n// gas legacyOptimized: 21813\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy.sol b/examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy.sol new file mode 100644 index 00000000..a9b99dd3 --- /dev/null +++ b/examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy.sol @@ -0,0 +1,17 @@ + +contract C { + function f(uint[] calldata arr) external returns (uint) { + return arr.sum(); + } +} + +function sum(uint[] memory arr) returns (uint result) { + for(uint i = 0; i < arr.length; i++) { + result += arr[i]; + } +} + +using {sum} for uint[]; + +// ---- +// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11 diff --git a/examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy_standard_input.json b/examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy_standard_input.json new file mode 100644 index 00000000..5612fe4c --- /dev/null +++ b/examples/test/semanticTests/using_calldata_memory_copy/calldata_memory_copy_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_free_function_braces/free_function_braces.sol b/examples/test/semanticTests/using_free_function_braces/free_function_braces.sol new file mode 100644 index 00000000..897914b9 --- /dev/null +++ b/examples/test/semanticTests/using_free_function_braces/free_function_braces.sol @@ -0,0 +1,24 @@ +function id(uint x) pure returns (uint) { + return x; +} + +function zero(uint) pure returns (uint) { + return 0; +} + +contract C { + function f(uint z) pure external returns(uint) { + return z.id(); + } + + function g(uint z) pure external returns (uint) { + return z.zero(); + } + + using {id, zero} for uint; +} +// ---- +// f(uint256): 10 -> 10 +// g(uint256): 10 -> 0 +// f(uint256): 256 -> 0x0100 +// g(uint256): 256 -> 0 diff --git a/examples/test/semanticTests/using_free_function_braces/free_function_braces_standard_input.json b/examples/test/semanticTests/using_free_function_braces/free_function_braces_standard_input.json new file mode 100644 index 00000000..6b0e5a6a --- /dev/null +++ b/examples/test/semanticTests/using_free_function_braces/free_function_braces_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + }, + "using_global_library.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1, T r2) {\n r1 = r1.inc().inc();\n r2 = r1.dec();\n }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n" + }, + "private_library_function.sol": { + "content": "library L {\n using {L.privateFunction} for uint;\n function privateFunction(uint x) private pure returns (uint) { return x + 1; }\n function f() public pure returns (uint) {\n uint x = 1;\n return x.privateFunction();\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_global_all_the_types.sol": { + "content": "==== Source: A ====\nenum E {A, B}\nstruct S { uint x; }\ntype T is uint;\nusing L for E global;\nusing L for S global;\nusing L for T global;\nlibrary L {\n function f(E e) internal pure returns (uint) {\n return uint(e);\n }\n function f(S memory s) internal pure returns (uint) {\n return s.x;\n }\n function f(T t) internal pure returns (uint) {\n return T.unwrap(t);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (uint a, uint b, uint c) {\n E e = E.B;\n a = e.f();\n S memory s;\n s.x = 7;\n b = s.f();\n T t = T.wrap(9);\n c = t.f();\n }\n}\n\nimport {E, S, T} from \"A\";\n\n// ----\n// f() -> 1, 7, 9\n" + }, + "free_function_braces.sol": { + "content": "function id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n\ncontract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n\n using {id, zero} for uint;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_free_function_multi/free_function_multi.sol b/examples/test/semanticTests/using_free_function_multi/free_function_multi.sol new file mode 100644 index 00000000..31ac50bc --- /dev/null +++ b/examples/test/semanticTests/using_free_function_multi/free_function_multi.sol @@ -0,0 +1,24 @@ +contract C { + function f(uint z) pure external returns(uint) { + return z.id(); + } + + using {id, zero, zero, id} for uint; + + function g(uint z) pure external returns (uint) { + return z.zero(); + } +} + +function id(uint x) pure returns (uint) { + return x; +} + +function zero(uint) pure returns (uint) { + return 0; +} +// ---- +// f(uint256): 10 -> 10 +// g(uint256): 10 -> 0 +// f(uint256): 256 -> 0x0100 +// g(uint256): 256 -> 0 diff --git a/examples/test/semanticTests/using_free_function_multi/free_function_multi_standard_input.json b/examples/test/semanticTests/using_free_function_multi/free_function_multi_standard_input.json new file mode 100644 index 00000000..5b12d35f --- /dev/null +++ b/examples/test/semanticTests/using_free_function_multi/free_function_multi_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_free_functions_individual/free_functions_individual.sol b/examples/test/semanticTests/using_free_functions_individual/free_functions_individual.sol new file mode 100644 index 00000000..5a14cd7c --- /dev/null +++ b/examples/test/semanticTests/using_free_functions_individual/free_functions_individual.sol @@ -0,0 +1,26 @@ +using {zero} for uint; + +contract C { + using {id} for uint; + + function f(uint z) pure external returns(uint) { + return z.id(); + } + + function g(uint z) pure external returns (uint) { + return z.zero(); + } +} + +function id(uint x) pure returns (uint) { + return x; +} + +function zero(uint) pure returns (uint) { + return 0; +} +// ---- +// f(uint256): 10 -> 10 +// g(uint256): 10 -> 0 +// f(uint256): 256 -> 0x0100 +// g(uint256): 256 -> 0 diff --git a/examples/test/semanticTests/using_free_functions_individual/free_functions_individual_standard_input.json b/examples/test/semanticTests/using_free_functions_individual/free_functions_individual_standard_input.json new file mode 100644 index 00000000..f4a8cd8f --- /dev/null +++ b/examples/test/semanticTests/using_free_functions_individual/free_functions_individual_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_imported_functions/imported_functions.sol b/examples/test/semanticTests/using_imported_functions/imported_functions.sol new file mode 100644 index 00000000..60a801ba --- /dev/null +++ b/examples/test/semanticTests/using_imported_functions/imported_functions.sol @@ -0,0 +1,17 @@ +==== Source: A ==== +function inc(uint x) pure returns (uint) { + return x + 1; +} + +==== Source: B ==== +contract C { + function f(uint x) public returns (uint) { + return x.f() + x.inc(); + } +} +using {A.inc, f} for uint; +import {inc as f} from "A"; +import "A" as A; +// ---- +// f(uint256): 5 -> 12 +// f(uint256): 10 -> 0x16 diff --git a/examples/test/semanticTests/using_imported_functions/imported_functions_standard_input.json b/examples/test/semanticTests/using_imported_functions/imported_functions_standard_input.json new file mode 100644 index 00000000..4d1d7db7 --- /dev/null +++ b/examples/test/semanticTests/using_imported_functions/imported_functions_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + }, + "using_global_library.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1, T r2) {\n r1 = r1.inc().inc();\n r2 = r1.dec();\n }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n" + }, + "private_library_function.sol": { + "content": "library L {\n using {L.privateFunction} for uint;\n function privateFunction(uint x) private pure returns (uint) { return x + 1; }\n function f() public pure returns (uint) {\n uint x = 1;\n return x.privateFunction();\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_global_all_the_types.sol": { + "content": "==== Source: A ====\nenum E {A, B}\nstruct S { uint x; }\ntype T is uint;\nusing L for E global;\nusing L for S global;\nusing L for T global;\nlibrary L {\n function f(E e) internal pure returns (uint) {\n return uint(e);\n }\n function f(S memory s) internal pure returns (uint) {\n return s.x;\n }\n function f(T t) internal pure returns (uint) {\n return T.unwrap(t);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (uint a, uint b, uint c) {\n E e = E.B;\n a = e.f();\n S memory s;\n s.x = 7;\n b = s.f();\n T t = T.wrap(9);\n c = t.f();\n }\n}\n\nimport {E, S, T} from \"A\";\n\n// ----\n// f() -> 1, 7, 9\n" + }, + "free_function_braces.sol": { + "content": "function id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n\ncontract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n\n using {id, zero} for uint;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "imported_functions.sol": { + "content": "==== Source: A ====\nfunction inc(uint x) pure returns (uint) {\n return x + 1;\n}\n\n==== Source: B ====\ncontract C {\n\tfunction f(uint x) public returns (uint) {\n return x.f() + x.inc();\n }\n}\nusing {A.inc, f} for uint;\nimport {inc as f} from \"A\";\nimport \"A\" as A;\n// ----\n// f(uint256): 5 -> 12\n// f(uint256): 10 -> 0x16\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract.sol b/examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract.sol new file mode 100644 index 00000000..170bc785 --- /dev/null +++ b/examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract.sol @@ -0,0 +1,31 @@ +library L { + function externalFunction(uint a) external pure returns (uint) { return a * 1; } + function publicFunction(uint b) public pure returns (uint) { return b * 2; } + function internalFunction(uint c) internal pure returns (uint) { return c * 3; } +} + +contract C { + using {L.externalFunction} for uint; + using {L.publicFunction} for uint; + using {L.internalFunction} for uint; + + function f() public pure returns (uint) { + uint x = 1; + return x.externalFunction(); + } + + function g() public pure returns (uint) { + uint x = 1; + return x.publicFunction(); + } + + function h() public pure returns (uint) { + uint x = 1; + return x.internalFunction(); + } +} +// ---- +// library: L +// f() -> 1 +// g() -> 2 +// h() -> 3 diff --git a/examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract_standard_input.json b/examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract_standard_input.json new file mode 100644 index 00000000..6b2cd5f8 --- /dev/null +++ b/examples/test/semanticTests/using_library_functions_inside_contract/library_functions_inside_contract_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_library_on_interface/library_on_interface.sol b/examples/test/semanticTests/using_library_on_interface/library_on_interface.sol new file mode 100644 index 00000000..48553c21 --- /dev/null +++ b/examples/test/semanticTests/using_library_on_interface/library_on_interface.sol @@ -0,0 +1,16 @@ +using L for I; +interface I { function f() external pure returns (uint); } +library L { + function execute(I i) internal pure returns (uint) { + return i.f(); + } +} +contract C is I { + function x() public view returns (uint) { + I i = this; + return i.execute(); + } + function f() public pure returns (uint) { return 7; } +} +// ---- +// x() -> 7 diff --git a/examples/test/semanticTests/using_library_on_interface/library_on_interface_standard_input.json b/examples/test/semanticTests/using_library_on_interface/library_on_interface_standard_input.json new file mode 100644 index 00000000..79f7ee0d --- /dev/null +++ b/examples/test/semanticTests/using_library_on_interface/library_on_interface_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_library_through_module/library_through_module.sol b/examples/test/semanticTests/using_library_through_module/library_through_module.sol new file mode 100644 index 00000000..cb33613c --- /dev/null +++ b/examples/test/semanticTests/using_library_through_module/library_through_module.sol @@ -0,0 +1,32 @@ +==== Source: A ==== +library L { + function id(uint x) internal pure returns (uint) { + return x; + } + function one_ext(uint) pure external returns(uint) { + return 1; + } + function empty() pure internal { + } + +} + +==== Source: B ==== +contract C { + using M.L for uint; + function f(uint x) public pure returns (uint) { + return x.id(); + } + function g(uint x) public pure returns (uint) { + return x.one_ext(); + } +} + +import "A" as M; + +// ---- +// library: "A":L +// f(uint256): 5 -> 5 +// f(uint256): 10 -> 10 +// g(uint256): 5 -> 1 +// g(uint256): 10 -> 1 diff --git a/examples/test/semanticTests/using_library_through_module/library_through_module_standard_input.json b/examples/test/semanticTests/using_library_through_module/library_through_module_standard_input.json new file mode 100644 index 00000000..d7e047f3 --- /dev/null +++ b/examples/test/semanticTests/using_library_through_module/library_through_module_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_module_renamed/module_renamed.sol b/examples/test/semanticTests/using_module_renamed/module_renamed.sol new file mode 100644 index 00000000..427e220f --- /dev/null +++ b/examples/test/semanticTests/using_module_renamed/module_renamed.sol @@ -0,0 +1,24 @@ +==== Source: A ==== +function f(uint x) pure returns (uint) { + return x + 2; +} +function g(uint x) pure returns (uint) { + return x + 8; +} + +==== Source: B ==== +import {f as g, g as f} from "A"; + +==== Source: C ==== +contract C { + function test(uint x, uint y) public pure returns (uint, uint) { + return (x.f(), y.g()); + } +} + +using {M.g, M.f} for uint; + +import "B" as M; + +// ---- +// test(uint256,uint256): 1, 1 -> 9, 3 diff --git a/examples/test/semanticTests/using_module_renamed/module_renamed_standard_input.json b/examples/test/semanticTests/using_module_renamed/module_renamed_standard_input.json new file mode 100644 index 00000000..3c2bdbeb --- /dev/null +++ b/examples/test/semanticTests/using_module_renamed/module_renamed_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_private_library_function/private_library_function.sol b/examples/test/semanticTests/using_private_library_function/private_library_function.sol new file mode 100644 index 00000000..e1440492 --- /dev/null +++ b/examples/test/semanticTests/using_private_library_function/private_library_function.sol @@ -0,0 +1,10 @@ +library L { + using {L.privateFunction} for uint; + function privateFunction(uint x) private pure returns (uint) { return x + 1; } + function f() public pure returns (uint) { + uint x = 1; + return x.privateFunction(); + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/using_private_library_function/private_library_function_standard_input.json b/examples/test/semanticTests/using_private_library_function/private_library_function_standard_input.json new file mode 100644 index 00000000..0ec871e3 --- /dev/null +++ b/examples/test/semanticTests/using_private_library_function/private_library_function_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + }, + "using_global_library.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1, T r2) {\n r1 = r1.inc().inc();\n r2 = r1.dec();\n }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n" + }, + "private_library_function.sol": { + "content": "library L {\n using {L.privateFunction} for uint;\n function privateFunction(uint x) private pure returns (uint) { return x + 1; }\n function f() public pure returns (uint) {\n uint x = 1;\n return x.privateFunction();\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_recursive_import/recursive_import.sol b/examples/test/semanticTests/using_recursive_import/recursive_import.sol new file mode 100644 index 00000000..6c896259 --- /dev/null +++ b/examples/test/semanticTests/using_recursive_import/recursive_import.sol @@ -0,0 +1,23 @@ +==== Source: A ==== +import {T as U} from "A"; +import "A" as X; + +type T is uint; +function f(T x) pure returns (T) { return T.wrap(T.unwrap(x) + 1); } +function g(T x) pure returns (uint) { return T.unwrap(x) + 10; } + +using { f } for X.X.U global; +using { g } for T global; + +function cr() pure returns (T) {} + +==== Source: B ==== +import { cr } from "A"; + +contract C { + function f() public returns (uint) { + return cr().f().g(); + } +} +// ---- +// f() -> 11 diff --git a/examples/test/semanticTests/using_recursive_import/recursive_import_standard_input.json b/examples/test/semanticTests/using_recursive_import/recursive_import_standard_input.json new file mode 100644 index 00000000..b2fd8f52 --- /dev/null +++ b/examples/test/semanticTests/using_recursive_import/recursive_import_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + }, + "using_global_library.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1, T r2) {\n r1 = r1.inc().inc();\n r2 = r1.dec();\n }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n" + }, + "private_library_function.sol": { + "content": "library L {\n using {L.privateFunction} for uint;\n function privateFunction(uint x) private pure returns (uint) { return x + 1; }\n function f() public pure returns (uint) {\n uint x = 1;\n return x.privateFunction();\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_global_all_the_types.sol": { + "content": "==== Source: A ====\nenum E {A, B}\nstruct S { uint x; }\ntype T is uint;\nusing L for E global;\nusing L for S global;\nusing L for T global;\nlibrary L {\n function f(E e) internal pure returns (uint) {\n return uint(e);\n }\n function f(S memory s) internal pure returns (uint) {\n return s.x;\n }\n function f(T t) internal pure returns (uint) {\n return T.unwrap(t);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (uint a, uint b, uint c) {\n E e = E.B;\n a = e.f();\n S memory s;\n s.x = 7;\n b = s.f();\n T t = T.wrap(9);\n c = t.f();\n }\n}\n\nimport {E, S, T} from \"A\";\n\n// ----\n// f() -> 1, 7, 9\n" + }, + "free_function_braces.sol": { + "content": "function id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n\ncontract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n\n using {id, zero} for uint;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "imported_functions.sol": { + "content": "==== Source: A ====\nfunction inc(uint x) pure returns (uint) {\n return x + 1;\n}\n\n==== Source: B ====\ncontract C {\n\tfunction f(uint x) public returns (uint) {\n return x.f() + x.inc();\n }\n}\nusing {A.inc, f} for uint;\nimport {inc as f} from \"A\";\nimport \"A\" as A;\n// ----\n// f(uint256): 5 -> 12\n// f(uint256): 10 -> 0x16\n" + }, + "recursive_import.sol": { + "content": "==== Source: A ====\nimport {T as U} from \"A\";\nimport \"A\" as X;\n\ntype T is uint;\nfunction f(T x) pure returns (T) { return T.wrap(T.unwrap(x) + 1); }\nfunction g(T x) pure returns (uint) { return T.unwrap(x) + 10; }\n\nusing { f } for X.X.U global;\nusing { g } for T global;\n\nfunction cr() pure returns (T) {}\n\n==== Source: B ====\nimport { cr } from \"A\";\n\ncontract C {\n function f() public returns (uint) {\n return cr().f().g();\n }\n}\n// ----\n// f() -> 11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types.sol b/examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types.sol new file mode 100644 index 00000000..f19c0c0f --- /dev/null +++ b/examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types.sol @@ -0,0 +1,36 @@ +==== Source: A ==== +enum E {A, B} +struct S { uint x; } +type T is uint; +using L for E global; +using L for S global; +using L for T global; +library L { + function f(E e) internal pure returns (uint) { + return uint(e); + } + function f(S memory s) internal pure returns (uint) { + return s.x; + } + function f(T t) internal pure returns (uint) { + return T.unwrap(t); + } +} + +==== Source: B ==== +contract C { + function f() public pure returns (uint a, uint b, uint c) { + E e = E.B; + a = e.f(); + S memory s; + s.x = 7; + b = s.f(); + T t = T.wrap(9); + c = t.f(); + } +} + +import {E, S, T} from "A"; + +// ---- +// f() -> 1, 7, 9 diff --git a/examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types_standard_input.json b/examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types_standard_input.json new file mode 100644 index 00000000..dbc28b8a --- /dev/null +++ b/examples/test/semanticTests/using_using_global_all_the_types/using_global_all_the_types_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + }, + "using_global_library.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1, T r2) {\n r1 = r1.inc().inc();\n r2 = r1.dec();\n }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n" + }, + "private_library_function.sol": { + "content": "library L {\n using {L.privateFunction} for uint;\n function privateFunction(uint x) private pure returns (uint) { return x + 1; }\n function f() public pure returns (uint) {\n uint x = 1;\n return x.privateFunction();\n }\n}\n// ----\n// f() -> 2\n" + }, + "using_global_all_the_types.sol": { + "content": "==== Source: A ====\nenum E {A, B}\nstruct S { uint x; }\ntype T is uint;\nusing L for E global;\nusing L for S global;\nusing L for T global;\nlibrary L {\n function f(E e) internal pure returns (uint) {\n return uint(e);\n }\n function f(S memory s) internal pure returns (uint) {\n return s.x;\n }\n function f(T t) internal pure returns (uint) {\n return T.unwrap(t);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (uint a, uint b, uint c) {\n E e = E.B;\n a = e.f();\n S memory s;\n s.x = 7;\n b = s.f();\n T t = T.wrap(9);\n c = t.f();\n }\n}\n\nimport {E, S, T} from \"A\";\n\n// ----\n// f() -> 1, 7, 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_using_global_for_global/using_global_for_global.sol b/examples/test/semanticTests/using_using_global_for_global/using_global_for_global.sol new file mode 100644 index 00000000..67a31c34 --- /dev/null +++ b/examples/test/semanticTests/using_using_global_for_global/using_global_for_global.sol @@ -0,0 +1,17 @@ +==== Source: A ==== +type global is uint; +using { f } for global global; +function f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); } +==== Source: B ==== +import { global } from "A"; + +function g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); } + +contract C { + using { g } for global; + function f(global r) public pure returns (global) { + return r.f().g(); + } +} +// ---- +// f(uint256): 100 -> 111 \ No newline at end of file diff --git a/examples/test/semanticTests/using_using_global_for_global/using_global_for_global_standard_input.json b/examples/test/semanticTests/using_using_global_for_global/using_global_for_global_standard_input.json new file mode 100644 index 00000000..7fb3e665 --- /dev/null +++ b/examples/test/semanticTests/using_using_global_for_global/using_global_for_global_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_using_global_invisible/using_global_invisible.sol b/examples/test/semanticTests/using_using_global_invisible/using_global_invisible.sol new file mode 100644 index 00000000..19719801 --- /dev/null +++ b/examples/test/semanticTests/using_using_global_invisible/using_global_invisible.sol @@ -0,0 +1,44 @@ +==== Source: A ==== +type T is uint; +using L for T global; +library L { + function inc(T x) internal pure returns (T) { + return T.wrap(T.unwrap(x) + 1); + } + function dec(T x) external pure returns (T) { + return T.wrap(T.unwrap(x) - 1); + } +} +using {unwrap} for T global; +function unwrap(T x) pure returns (uint) { + return T.unwrap(x); +} + +==== Source: B ==== +contract C { + function f() public pure returns (T r1) { + r1 = r1.inc().inc(); + } +} + +import {T} from "A"; + +==== Source: C ==== +import {C} from "B"; + +contract D { + function test() public returns (uint) { + C c = new C(); + // This tests that attached functions are available + // even if the type is not available by name. + // This is a regular function call, a + // public and an internal library call + // and a free function call. + return c.f().inc().inc().dec().unwrap(); + } +} +// ---- +// library: "A":L +// test() -> 3 +// gas legacy: 59680 +// gas legacy code: 61200 diff --git a/examples/test/semanticTests/using_using_global_invisible/using_global_invisible_standard_input.json b/examples/test/semanticTests/using_using_global_invisible/using_global_invisible_standard_input.json new file mode 100644 index 00000000..ca17b327 --- /dev/null +++ b/examples/test/semanticTests/using_using_global_invisible/using_global_invisible_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/using_using_global_library/using_global_library.sol b/examples/test/semanticTests/using_using_global_library/using_global_library.sol new file mode 100644 index 00000000..f18024f3 --- /dev/null +++ b/examples/test/semanticTests/using_using_global_library/using_global_library.sol @@ -0,0 +1,25 @@ +==== Source: A ==== +type T is uint; +using L for T global; +library L { + function inc(T x) internal pure returns (T) { + return T.wrap(T.unwrap(x) + 1); + } + function dec(T x) external pure returns (T) { + return T.wrap(T.unwrap(x) - 1); + } +} + +==== Source: B ==== +contract C { + function f() public pure returns (T r1, T r2) { + r1 = r1.inc().inc(); + r2 = r1.dec(); + } +} + +import {T} from "A"; + +// ---- +// library: "A":L +// f() -> 2, 1 diff --git a/examples/test/semanticTests/using_using_global_library/using_global_library_standard_input.json b/examples/test/semanticTests/using_using_global_library/using_global_library_standard_input.json new file mode 100644 index 00000000..6f9058ee --- /dev/null +++ b/examples/test/semanticTests/using_using_global_library/using_global_library_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "using_global_invisible.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\nusing {unwrap} for T global;\nfunction unwrap(T x) pure returns (uint) {\n return T.unwrap(x);\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1) {\n r1 = r1.inc().inc();\n }\n}\n\nimport {T} from \"A\";\n\n==== Source: C ====\nimport {C} from \"B\";\n\ncontract D {\n function test() public returns (uint) {\n C c = new C();\n // This tests that attached functions are available\n // even if the type is not available by name.\n // This is a regular function call, a\n // public and an internal library call\n // and a free function call.\n return c.f().inc().inc().dec().unwrap();\n }\n}\n// ----\n// library: \"A\":L\n// test() -> 3\n// gas legacy: 59680\n// gas legacy code: 61200\n" + }, + "free_function_multi.sol": { + "content": "contract C {\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n using {id, zero, zero, id} for uint;\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "free_functions_individual.sol": { + "content": "using {zero} for uint;\n\ncontract C {\n using {id} for uint;\n\n function f(uint z) pure external returns(uint) {\n return z.id();\n }\n\n function g(uint z) pure external returns (uint) {\n return z.zero();\n }\n}\n\nfunction id(uint x) pure returns (uint) {\n return x;\n}\n\nfunction zero(uint) pure returns (uint) {\n return 0;\n}\n// ----\n// f(uint256): 10 -> 10\n// g(uint256): 10 -> 0\n// f(uint256): 256 -> 0x0100\n// g(uint256): 256 -> 0\n" + }, + "using_global_for_global.sol": { + "content": "==== Source: A ====\ntype global is uint;\nusing { f } for global global;\nfunction f(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 1); }\n==== Source: B ====\nimport { global } from \"A\";\n\nfunction g(global x) pure returns (global) { return global.wrap(global.unwrap(x) + 10); }\n\ncontract C {\n using { g } for global;\n function f(global r) public pure returns (global) {\n return r.f().g();\n }\n}\n// ----\n// f(uint256): 100 -> 111" + }, + "module_renamed.sol": { + "content": "==== Source: A ====\nfunction f(uint x) pure returns (uint) {\n return x + 2;\n}\nfunction g(uint x) pure returns (uint) {\n return x + 8;\n}\n\n==== Source: B ====\nimport {f as g, g as f} from \"A\";\n\n==== Source: C ====\ncontract C {\n\tfunction test(uint x, uint y) public pure returns (uint, uint) {\n return (x.f(), y.g());\n }\n}\n\nusing {M.g, M.f} for uint;\n\nimport \"B\" as M;\n\n// ----\n// test(uint256,uint256): 1, 1 -> 9, 3\n" + }, + "calldata_memory_copy.sol": { + "content": "\ncontract C {\n function f(uint[] calldata arr) external returns (uint) {\n return arr.sum();\n }\n}\n\nfunction sum(uint[] memory arr) returns (uint result) {\n for(uint i = 0; i < arr.length; i++) {\n result += arr[i];\n }\n}\n\nusing {sum} for uint[];\n\n// ----\n// f(uint256[]): 0x20, 3, 1, 2, 8 -> 11\n" + }, + "library_through_module.sol": { + "content": "==== Source: A ====\nlibrary L {\n function id(uint x) internal pure returns (uint) {\n return x;\n }\n function one_ext(uint) pure external returns(uint) {\n return 1;\n }\n function empty() pure internal {\n }\n\n}\n\n==== Source: B ====\ncontract C {\n using M.L for uint;\n function f(uint x) public pure returns (uint) {\n return x.id();\n }\n function g(uint x) public pure returns (uint) {\n return x.one_ext();\n }\n}\n\nimport \"A\" as M;\n\n// ----\n// library: \"A\":L\n// f(uint256): 5 -> 5\n// f(uint256): 10 -> 10\n// g(uint256): 5 -> 1\n// g(uint256): 10 -> 1\n" + }, + "library_functions_inside_contract.sol": { + "content": "library L {\n function externalFunction(uint a) external pure returns (uint) { return a * 1; }\n function publicFunction(uint b) public pure returns (uint) { return b * 2; }\n function internalFunction(uint c) internal pure returns (uint) { return c * 3; }\n}\n\ncontract C {\n using {L.externalFunction} for uint;\n using {L.publicFunction} for uint;\n using {L.internalFunction} for uint;\n\n function f() public pure returns (uint) {\n uint x = 1;\n return x.externalFunction();\n }\n\n function g() public pure returns (uint) {\n uint x = 1;\n return x.publicFunction();\n }\n\n function h() public pure returns (uint) {\n uint x = 1;\n return x.internalFunction();\n }\n}\n// ----\n// library: L\n// f() -> 1\n// g() -> 2\n// h() -> 3\n" + }, + "library_on_interface.sol": { + "content": "using L for I;\ninterface I { function f() external pure returns (uint); }\nlibrary L {\n function execute(I i) internal pure returns (uint) {\n return i.f();\n }\n}\ncontract C is I {\n function x() public view returns (uint) {\n I i = this;\n return i.execute();\n }\n function f() public pure returns (uint) { return 7; }\n}\n// ----\n// x() -> 7\n" + }, + "using_global_library.sol": { + "content": "==== Source: A ====\ntype T is uint;\nusing L for T global;\nlibrary L {\n function inc(T x) internal pure returns (T) {\n return T.wrap(T.unwrap(x) + 1);\n }\n function dec(T x) external pure returns (T) {\n return T.wrap(T.unwrap(x) - 1);\n }\n}\n\n==== Source: B ====\ncontract C {\n function f() public pure returns (T r1, T r2) {\n r1 = r1.inc().inc();\n r2 = r1.dec();\n }\n}\n\nimport {T} from \"A\";\n\n// ----\n// library: \"A\":L\n// f() -> 2, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_delete_local/delete_local.sol b/examples/test/semanticTests/variables_delete_local/delete_local.sol new file mode 100644 index 00000000..1d00bace --- /dev/null +++ b/examples/test/semanticTests/variables_delete_local/delete_local.sol @@ -0,0 +1,9 @@ +contract test { + function delLocal() public returns (uint res){ + uint v = 5; + delete v; + res = v; + } +} +// ---- +// delLocal() -> 0 diff --git a/examples/test/semanticTests/variables_delete_local/delete_local_standard_input.json b/examples/test/semanticTests/variables_delete_local/delete_local_standard_input.json new file mode 100644 index 00000000..4ade9383 --- /dev/null +++ b/examples/test/semanticTests/variables_delete_local/delete_local_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_delete_locals/delete_locals.sol b/examples/test/semanticTests/variables_delete_locals/delete_locals.sol new file mode 100644 index 00000000..e442b8e8 --- /dev/null +++ b/examples/test/semanticTests/variables_delete_locals/delete_locals.sol @@ -0,0 +1,12 @@ +contract test { + function delLocal() public returns (uint res1, uint res2){ + uint v = 5; + uint w = 6; + uint x = 7; + delete v; + res1 = w; + res2 = x; + } +} +// ---- +// delLocal() -> 6, 7 diff --git a/examples/test/semanticTests/variables_delete_locals/delete_locals_standard_input.json b/examples/test/semanticTests/variables_delete_locals/delete_locals_standard_input.json new file mode 100644 index 00000000..85d1d406 --- /dev/null +++ b/examples/test/semanticTests/variables_delete_locals/delete_locals_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + }, + "delete_locals.sol": { + "content": "contract test {\n function delLocal() public returns (uint res1, uint res2){\n uint v = 5;\n uint w = 6;\n uint x = 7;\n delete v;\n res1 = w;\n res2 = x;\n }\n}\n// ----\n// delLocal() -> 6, 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable.sol b/examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable.sol new file mode 100644 index 00000000..868149eb --- /dev/null +++ b/examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable.sol @@ -0,0 +1,12 @@ +contract C { + uint transient x; + function f() public returns (uint) { + x = 10; + delete x; + return x; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable_standard_input.json b/examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable_standard_input.json new file mode 100644 index 00000000..72031140 --- /dev/null +++ b/examples/test/semanticTests/variables_delete_transient_state_variable/delete_transient_state_variable_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset.sol b/examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset.sol new file mode 100644 index 00000000..96dfce60 --- /dev/null +++ b/examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset.sol @@ -0,0 +1,17 @@ +contract C { + bytes14 transient x; + uint32 transient y; + uint112 transient z; + + function f() public returns (bytes14, uint32, uint112) { + x = 0xffffffffffffffffffffffffffff; + y = 0xffffffff; + z = 0xffffffffffffffffffffffffffff; + delete y; + return (x, y, z); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff diff --git a/examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset_standard_input.json b/examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset_standard_input.json new file mode 100644 index 00000000..99238151 --- /dev/null +++ b/examples/test/semanticTests/variables_delete_transient_state_variable_non_zero_offset/delete_transient_state_variable_non_zero_offset_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment.sol b/examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment.sol new file mode 100644 index 00000000..b9938582 --- /dev/null +++ b/examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment.sol @@ -0,0 +1,15 @@ +contract test { + mapping(uint8 => uint8) m1; + mapping(uint8 => uint8) m2; + function f() public returns (uint8, uint8, uint8, uint8) { + mapping(uint8 => uint8) storage m = m1; + m[1] = 42; + + m = m2; + m[2] = 21; + + return (m1[1], m1[2], m2[1], m2[2]); + } +} +// ---- +// f() -> 42, 0, 0, 21 diff --git a/examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment_standard_input.json b/examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment_standard_input.json new file mode 100644 index 00000000..66a76de9 --- /dev/null +++ b/examples/test/semanticTests/variables_mapping_local_assignment/mapping_local_assignment_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment.sol b/examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment.sol new file mode 100644 index 00000000..df3ee2f5 --- /dev/null +++ b/examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment.sol @@ -0,0 +1,14 @@ +contract test { + mapping(uint8 => uint8) m1; + mapping(uint8 => uint8) m2; + function f() public returns (uint8, uint8, uint8, uint8) { + mapping(uint8 => uint8) storage m = m1; + m[1] = 42; + + (m = m2)[2] = 21; + + return (m1[1], m1[2], m2[1], m2[2]); + } +} +// ---- +// f() -> 42, 0, 0, 21 diff --git a/examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment_standard_input.json b/examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment_standard_input.json new file mode 100644 index 00000000..d8c56c60 --- /dev/null +++ b/examples/test/semanticTests/variables_mapping_local_compound_assignment/mapping_local_compound_assignment_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment.sol b/examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment.sol new file mode 100644 index 00000000..39dd04ab --- /dev/null +++ b/examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment.sol @@ -0,0 +1,16 @@ +contract test { + mapping(uint8 => uint8) m1; + mapping(uint8 => uint8) m2; + function f() public returns (uint8, uint8, uint8, uint8) { + mapping(uint8 => uint8) storage m = m1; + m[1] = 42; + + uint8 v; + (m, v) = (m2, 21); + m[2] = v; + + return (m1[1], m1[2], m2[1], m2[2]); + } +} +// ---- +// f() -> 42, 0, 0, 21 diff --git a/examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment_standard_input.json b/examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment_standard_input.json new file mode 100644 index 00000000..67f21eb5 --- /dev/null +++ b/examples/test/semanticTests/variables_mapping_local_tuple_assignment/mapping_local_tuple_assignment_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_public_state_overridding/public_state_overridding.sol b/examples/test/semanticTests/variables_public_state_overridding/public_state_overridding.sol new file mode 100644 index 00000000..78e0fb44 --- /dev/null +++ b/examples/test/semanticTests/variables_public_state_overridding/public_state_overridding.sol @@ -0,0 +1,17 @@ +contract A +{ + function test() external virtual returns (uint256) + { + return 5; + } +} +contract X is A +{ + uint256 public override test; + + function set() public { test = 2; } +} +// ---- +// test() -> 0 +// set() -> +// test() -> 2 diff --git a/examples/test/semanticTests/variables_public_state_overridding/public_state_overridding_standard_input.json b/examples/test/semanticTests/variables_public_state_overridding/public_state_overridding_standard_input.json new file mode 100644 index 00000000..7ca44dbc --- /dev/null +++ b/examples/test/semanticTests/variables_public_state_overridding/public_state_overridding_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct.sol b/examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct.sol new file mode 100644 index 00000000..15226b5e --- /dev/null +++ b/examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct.sol @@ -0,0 +1,22 @@ +pragma abicoder v2; + +struct S { uint256 v; string s; } + +contract A +{ + function test() external virtual returns (uint256 v, string memory s) + { + v = 42; + s = "test"; + } +} +contract X is A +{ + S public override test; + + function set() public { test.v = 2; test.s = "statevar"; } +} +// ---- +// test() -> 0, 64, 0 +// set() -> +// test() -> 2, 0x40, 8, "statevar" diff --git a/examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct_standard_input.json b/examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct_standard_input.json new file mode 100644 index 00000000..b351f446 --- /dev/null +++ b/examples/test/semanticTests/variables_public_state_overridding_dynamic_struct/public_state_overridding_dynamic_struct_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + }, + "delete_locals.sol": { + "content": "contract test {\n function delLocal() public returns (uint res1, uint res2){\n uint v = 5;\n uint w = 6;\n uint x = 7;\n delete v;\n res1 = w;\n res2 = x;\n }\n}\n// ----\n// delLocal() -> 6, 7\n" + }, + "storing_invalid_boolean.sol": { + "content": "contract C {\n event Ev(bool);\n bool public perm;\n function set() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n perm = tmp;\n return 1;\n }\n function ret() public returns(bool) {\n bool tmp;\n assembly {\n tmp := 5\n }\n return tmp;\n }\n function ev() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n emit Ev(tmp);\n return 1;\n }\n}\n// ----\n// set() -> 1\n// perm() -> true\n// ret() -> true\n// ev() -> 1\n// ~ emit Ev(bool): true\n" + }, + "transient_state_variable_slots_and_offsets.sol": { + "content": "contract C {\n uint128 transient x;\n uint64 transient y;\n uint64 transient w;\n uint256 transient z;\n\n function f() external returns (uint128, uint64, uint64, uint256) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n return (x, y, w, z);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n" + }, + "transient_state_variable_udvt.sol": { + "content": "type MyInt is int256;\ncontract C {\n MyInt transient public x;\n\n function f() public {\n x = MyInt.wrap(2);\n }\n function g() public returns (MyInt) {\n x = MyInt.wrap(0);\n this.f();\n return x;\n }\n function h() public returns (MyInt) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 2\n// h() -> 0\n" + }, + "transient_state_enum_variable.sol": { + "content": "contract C {\n enum Pets { Dog, Cat, Bird, Fish }\n Pets transient myPet;\n\n function f() public {\n myPet = Pets.Bird;\n this.g();\n assert(myPet == Pets.Cat);\n }\n function g() public {\n myPet = Pets.Cat;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n" + }, + "public_state_overridding_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test() external virtual returns (uint256 v, string memory s)\n\t{\n\t v = 42;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tS public override test;\n\n\tfunction set() public { test.v = 2; test.s = \"statevar\"; }\n}\n// ----\n// test() -> 0, 64, 0\n// set() ->\n// test() -> 2, 0x40, 8, \"statevar\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct.sol b/examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct.sol new file mode 100644 index 00000000..62aa616e --- /dev/null +++ b/examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; + +struct S { uint256 v; string s; } + +contract A +{ + function test(uint256 x) external virtual returns (uint256 v, string memory s) + { + v = x; + s = "test"; + } +} +contract X is A +{ + mapping(uint256 => S) public override test; + + function set() public { test[42].v = 2; test[42].s = "statevar"; } +} +// ---- +// test(uint256): 0 -> 0, 64, 0 +// test(uint256): 42 -> 0, 64, 0 +// set() -> +// test(uint256): 0 -> 0, 64, 0 +// test(uint256): 42 -> 2, 0x40, 8, "statevar" diff --git a/examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct_standard_input.json b/examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct_standard_input.json new file mode 100644 index 00000000..d63ccd07 --- /dev/null +++ b/examples/test/semanticTests/variables_public_state_overridding_mapping_to_dynamic_struct/public_state_overridding_mapping_to_dynamic_struct_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean.sol b/examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean.sol new file mode 100644 index 00000000..7a4d3620 --- /dev/null +++ b/examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean.sol @@ -0,0 +1,33 @@ +contract C { + event Ev(bool); + bool public perm; + function set() public returns(uint) { + bool tmp; + assembly { + tmp := 5 + } + perm = tmp; + return 1; + } + function ret() public returns(bool) { + bool tmp; + assembly { + tmp := 5 + } + return tmp; + } + function ev() public returns(uint) { + bool tmp; + assembly { + tmp := 5 + } + emit Ev(tmp); + return 1; + } +} +// ---- +// set() -> 1 +// perm() -> true +// ret() -> true +// ev() -> 1 +// ~ emit Ev(bool): true diff --git a/examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean_standard_input.json b/examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean_standard_input.json new file mode 100644 index 00000000..b7b4ac6f --- /dev/null +++ b/examples/test/semanticTests/variables_storing_invalid_boolean/storing_invalid_boolean_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + }, + "delete_locals.sol": { + "content": "contract test {\n function delLocal() public returns (uint res1, uint res2){\n uint v = 5;\n uint w = 6;\n uint x = 7;\n delete v;\n res1 = w;\n res2 = x;\n }\n}\n// ----\n// delLocal() -> 6, 7\n" + }, + "storing_invalid_boolean.sol": { + "content": "contract C {\n event Ev(bool);\n bool public perm;\n function set() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n perm = tmp;\n return 1;\n }\n function ret() public returns(bool) {\n bool tmp;\n assembly {\n tmp := 5\n }\n return tmp;\n }\n function ev() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n emit Ev(tmp);\n return 1;\n }\n}\n// ----\n// set() -> 1\n// perm() -> true\n// ret() -> true\n// ev() -> 1\n// ~ emit Ev(bool): true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable.sol b/examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable.sol new file mode 100644 index 00000000..eb9d00fa --- /dev/null +++ b/examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable.sol @@ -0,0 +1,16 @@ +contract C { + function () external transient f; + function g() external { + } + + function test() public returns (bool) { + assert(f != this.g); + f = this.g; + + return f == this.g; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// test() -> true diff --git a/examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable_standard_input.json b/examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable_standard_input.json new file mode 100644 index 00000000..fd2f69a4 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_function_type_state_variable/transient_function_type_state_variable_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members.sol b/examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members.sol new file mode 100644 index 00000000..f609f9d4 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members.sol @@ -0,0 +1,20 @@ +contract C { + address transient a; + function f() public returns (uint) { + a = msg.sender; + return a.balance; + } + function g() public returns (uint) { + return a.balance; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// constructor() -> +// gas legacy: 59027 +// gas legacy code: 70400 +// account: 0 -> 0x1212121212121212121212121212120000000012 +// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376 +// f() -> 1267650600228229401496703205376 +// g() -> 0 diff --git a/examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members_standard_input.json b/examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members_standard_input.json new file mode 100644 index 00000000..180730d6 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_address_variable_members/transient_state_address_variable_members_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable.sol b/examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable.sol new file mode 100644 index 00000000..e260ebad --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable.sol @@ -0,0 +1,17 @@ +contract C { + enum Pets { Dog, Cat, Bird, Fish } + Pets transient myPet; + + function f() public { + myPet = Pets.Bird; + this.g(); + assert(myPet == Pets.Cat); + } + function g() public { + myPet = Pets.Cat; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> diff --git a/examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable_standard_input.json b/examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable_standard_input.json new file mode 100644 index 00000000..75824214 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_enum_variable/transient_state_enum_variable_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + }, + "delete_locals.sol": { + "content": "contract test {\n function delLocal() public returns (uint res1, uint res2){\n uint v = 5;\n uint w = 6;\n uint x = 7;\n delete v;\n res1 = w;\n res2 = x;\n }\n}\n// ----\n// delLocal() -> 6, 7\n" + }, + "storing_invalid_boolean.sol": { + "content": "contract C {\n event Ev(bool);\n bool public perm;\n function set() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n perm = tmp;\n return 1;\n }\n function ret() public returns(bool) {\n bool tmp;\n assembly {\n tmp := 5\n }\n return tmp;\n }\n function ev() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n emit Ev(tmp);\n return 1;\n }\n}\n// ----\n// set() -> 1\n// perm() -> true\n// ret() -> true\n// ev() -> 1\n// ~ emit Ev(bool): true\n" + }, + "transient_state_variable_slots_and_offsets.sol": { + "content": "contract C {\n uint128 transient x;\n uint64 transient y;\n uint64 transient w;\n uint256 transient z;\n\n function f() external returns (uint128, uint64, uint64, uint256) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n return (x, y, w, z);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n" + }, + "transient_state_variable_udvt.sol": { + "content": "type MyInt is int256;\ncontract C {\n MyInt transient public x;\n\n function f() public {\n x = MyInt.wrap(2);\n }\n function g() public returns (MyInt) {\n x = MyInt.wrap(0);\n this.f();\n return x;\n }\n function h() public returns (MyInt) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 2\n// h() -> 0\n" + }, + "transient_state_enum_variable.sol": { + "content": "contract C {\n enum Pets { Dog, Cat, Bird, Fish }\n Pets transient myPet;\n\n function f() public {\n myPet = Pets.Bird;\n this.g();\n assert(myPet == Pets.Cat);\n }\n function g() public {\n myPet = Pets.Cat;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable/transient_state_variable.sol b/examples/test/semanticTests/variables_transient_state_variable/transient_state_variable.sol new file mode 100644 index 00000000..03163982 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable/transient_state_variable.sol @@ -0,0 +1,21 @@ +contract C { + uint transient public x; + + function f() public { + x = 8; + } + function g() public returns (uint) { + x = 0; + this.f(); + return x; + } + function h() public returns (uint) { + return x; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// x() -> 0 +// g() -> 8 +// h() -> 0 diff --git a/examples/test/semanticTests/variables_transient_state_variable/transient_state_variable_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable/transient_state_variable_standard_input.json new file mode 100644 index 00000000..c48a3da9 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable/transient_state_variable_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment.sol b/examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment.sol new file mode 100644 index 00000000..a81572ec --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment.sol @@ -0,0 +1,16 @@ +contract C { + uint8 transient x; + function f() public returns(uint256 r) { + uint8 y; + assembly { y := 0xFFFF } + x = y; + assembly { + r := tload(x.slot) + } + + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0xff diff --git a/examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment_standard_input.json new file mode 100644 index 00000000..2f5c5293 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_cleanup_assignment/transient_state_variable_cleanup_assignment_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore.sol b/examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore.sol new file mode 100644 index 00000000..8f3be7ae --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore.sol @@ -0,0 +1,14 @@ +contract C { + uint8 transient x; + function f() public returns(uint256 r) { + assembly { + tstore(x.slot, 0xFFFF) + } + return x; + + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0xff diff --git a/examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore_standard_input.json new file mode 100644 index 00000000..bcbbf1b6 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_cleanup_tstore/transient_state_variable_cleanup_tstore_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly.sol b/examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly.sol new file mode 100644 index 00000000..0e7f29ed --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly.sol @@ -0,0 +1,31 @@ +contract C { + uint256 y; + uint256 transient x; + int8 transient w; + int z; + address transient a; + function f() public returns(uint256 s, uint256 o) { + assembly { + s := x.slot + o := x.offset + } + } + function g() public returns(uint256 s, uint256 o) { + assembly { + s := w.slot + o := w.offset + } + } + function h() public returns(uint256 s, uint256 o) { + assembly { + s := a.slot + o := a.offset + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 0, 0 +// g() -> 1, 0 +// h() -> 1, 1 diff --git a/examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly_standard_input.json new file mode 100644 index 00000000..231bb675 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_slot_inline_assembly/transient_state_variable_slot_inline_assembly_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets.sol b/examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets.sol new file mode 100644 index 00000000..63f23e18 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets.sol @@ -0,0 +1,20 @@ +contract C { + uint128 transient x; + uint64 transient y; + uint64 transient w; + uint256 transient z; + + function f() external returns (uint128, uint64, uint64, uint256) { + x = 1; + y = 2; + w = 3; + z = 4; + + return (x, y, w, z); + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1, 2, 3, 4 diff --git a/examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets_standard_input.json new file mode 100644 index 00000000..dbe5cf1e --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_slots_and_offsets/transient_state_variable_slots_and_offsets_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + }, + "delete_locals.sol": { + "content": "contract test {\n function delLocal() public returns (uint res1, uint res2){\n uint v = 5;\n uint w = 6;\n uint x = 7;\n delete v;\n res1 = w;\n res2 = x;\n }\n}\n// ----\n// delLocal() -> 6, 7\n" + }, + "storing_invalid_boolean.sol": { + "content": "contract C {\n event Ev(bool);\n bool public perm;\n function set() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n perm = tmp;\n return 1;\n }\n function ret() public returns(bool) {\n bool tmp;\n assembly {\n tmp := 5\n }\n return tmp;\n }\n function ev() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n emit Ev(tmp);\n return 1;\n }\n}\n// ----\n// set() -> 1\n// perm() -> true\n// ret() -> true\n// ev() -> 1\n// ~ emit Ev(bool): true\n" + }, + "transient_state_variable_slots_and_offsets.sol": { + "content": "contract C {\n uint128 transient x;\n uint64 transient y;\n uint64 transient w;\n uint256 transient z;\n\n function f() external returns (uint128, uint64, uint64, uint256) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n return (x, y, w, z);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment.sol b/examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment.sol new file mode 100644 index 00000000..37912662 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment.sol @@ -0,0 +1,20 @@ +contract C { + uint transient x; + uint y; + uint transient w; + uint z; + + function f() public returns (uint, uint, uint) { + x = 1; + y = 2; + w = 3; + z = 4; + + (x, y, w) = (y, w, z); + return (x, y, w); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 2, 3, 4 diff --git a/examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment_standard_input.json new file mode 100644 index 00000000..315242c1 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_tuple_assignment/transient_state_variable_tuple_assignment_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt.sol b/examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt.sol new file mode 100644 index 00000000..1829491f --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt.sol @@ -0,0 +1,22 @@ +type MyInt is int256; +contract C { + MyInt transient public x; + + function f() public { + x = MyInt.wrap(2); + } + function g() public returns (MyInt) { + x = MyInt.wrap(0); + this.f(); + return x; + } + function h() public returns (MyInt) { + return x; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// x() -> 0 +// g() -> 2 +// h() -> 0 diff --git a/examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt_standard_input.json b/examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt_standard_input.json new file mode 100644 index 00000000..f211a426 --- /dev/null +++ b/examples/test/semanticTests/variables_transient_state_variable_udvt/transient_state_variable_udvt_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "delete_transient_state_variable.sol": { + "content": "contract C {\n uint transient x;\n function f() public returns (uint) {\n x = 10;\n delete x;\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0\n" + }, + "transient_state_variable_cleanup_assignment.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n uint8 y;\n assembly { y := 0xFFFF }\n x = y;\n assembly {\n r := tload(x.slot)\n }\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "transient_state_variable_tuple_assignment.sol": { + "content": "contract C {\n uint transient x;\n uint y;\n uint transient w;\n uint z;\n\n function f() public returns (uint, uint, uint) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n (x, y, w) = (y, w, z);\n return (x, y, w);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 2, 3, 4\n" + }, + "public_state_overridding.sol": { + "content": "contract A\n{\n\tfunction test() external virtual returns (uint256)\n\t{\n\t\treturn 5;\n\t}\n}\ncontract X is A\n{\n\tuint256 public override test;\n\n\tfunction set() public { test = 2; }\n}\n// ----\n// test() -> 0\n// set() ->\n// test() -> 2\n" + }, + "transient_function_type_state_variable.sol": { + "content": "contract C {\n function () external transient f;\n function g() external {\n }\n\n function test() public returns (bool) {\n assert(f != this.g);\n f = this.g;\n\n return f == this.g;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test() -> true\n" + }, + "delete_transient_state_variable_non_zero_offset.sol": { + "content": "contract C {\n bytes14 transient x;\n uint32 transient y;\n uint112 transient z;\n\n function f() public returns (bytes14, uint32, uint112) {\n x = 0xffffffffffffffffffffffffffff;\n y = 0xffffffff;\n z = 0xffffffffffffffffffffffffffff;\n delete y;\n return (x, y, z);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xffffffffffffffffffffffffffff000000000000000000000000000000000000, 0, 0xffffffffffffffffffffffffffff\n" + }, + "mapping_local_compound_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n (m = m2)[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "transient_state_variable.sol": { + "content": "contract C {\n uint transient public x;\n\n function f() public {\n x = 8;\n }\n function g() public returns (uint) {\n x = 0;\n this.f();\n return x;\n }\n function h() public returns (uint) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 8\n// h() -> 0\n" + }, + "transient_state_variable_cleanup_tstore.sol": { + "content": "contract C {\n uint8 transient x;\n function f() public returns(uint256 r) {\n assembly {\n tstore(x.slot, 0xFFFF)\n }\n return x;\n\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0xff\n" + }, + "mapping_local_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n m = m2;\n m[2] = 21;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "mapping_local_tuple_assignment.sol": { + "content": "contract test {\n mapping(uint8 => uint8) m1;\n mapping(uint8 => uint8) m2;\n function f() public returns (uint8, uint8, uint8, uint8) {\n mapping(uint8 => uint8) storage m = m1;\n m[1] = 42;\n\n uint8 v;\n (m, v) = (m2, 21);\n m[2] = v;\n\n return (m1[1], m1[2], m2[1], m2[2]);\n }\n}\n// ----\n// f() -> 42, 0, 0, 21\n" + }, + "public_state_overridding_mapping_to_dynamic_struct.sol": { + "content": "pragma abicoder v2;\n\nstruct S { uint256 v; string s; }\n\ncontract A\n{\n\tfunction test(uint256 x) external virtual returns (uint256 v, string memory s)\n\t{\n\t v = x;\n\t s = \"test\";\n\t}\n}\ncontract X is A\n{\n\tmapping(uint256 => S) public override test;\n\n\tfunction set() public { test[42].v = 2; test[42].s = \"statevar\"; }\n}\n// ----\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 0, 64, 0\n// set() ->\n// test(uint256): 0 -> 0, 64, 0\n// test(uint256): 42 -> 2, 0x40, 8, \"statevar\"\n" + }, + "transient_state_address_variable_members.sol": { + "content": "contract C {\n address transient a;\n function f() public returns (uint) {\n a = msg.sender;\n return a.balance;\n }\n function g() public returns (uint) {\n return a.balance;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor() ->\n// gas legacy: 59027\n// gas legacy code: 70400\n// account: 0 -> 0x1212121212121212121212121212120000000012\n// balance: 0x1212121212121212121212121212120000000012 -> 1267650600228229401496703205376\n// f() -> 1267650600228229401496703205376\n// g() -> 0\n" + }, + "delete_local.sol": { + "content": "contract test {\n function delLocal() public returns (uint res){\n uint v = 5;\n delete v;\n res = v;\n }\n}\n// ----\n// delLocal() -> 0\n" + }, + "transient_state_variable_slot_inline_assembly.sol": { + "content": "contract C {\n uint256 y;\n uint256 transient x;\n int8 transient w;\n int z;\n address transient a;\n function f() public returns(uint256 s, uint256 o) {\n assembly {\n s := x.slot\n o := x.offset\n }\n }\n function g() public returns(uint256 s, uint256 o) {\n assembly {\n s := w.slot\n o := w.offset\n }\n }\n function h() public returns(uint256 s, uint256 o) {\n assembly {\n s := a.slot\n o := a.offset\n }\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 0, 0\n// g() -> 1, 0\n// h() -> 1, 1\n" + }, + "delete_locals.sol": { + "content": "contract test {\n function delLocal() public returns (uint res1, uint res2){\n uint v = 5;\n uint w = 6;\n uint x = 7;\n delete v;\n res1 = w;\n res2 = x;\n }\n}\n// ----\n// delLocal() -> 6, 7\n" + }, + "storing_invalid_boolean.sol": { + "content": "contract C {\n event Ev(bool);\n bool public perm;\n function set() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n perm = tmp;\n return 1;\n }\n function ret() public returns(bool) {\n bool tmp;\n assembly {\n tmp := 5\n }\n return tmp;\n }\n function ev() public returns(uint) {\n bool tmp;\n assembly {\n tmp := 5\n }\n emit Ev(tmp);\n return 1;\n }\n}\n// ----\n// set() -> 1\n// perm() -> true\n// ret() -> true\n// ev() -> 1\n// ~ emit Ev(bool): true\n" + }, + "transient_state_variable_slots_and_offsets.sol": { + "content": "contract C {\n uint128 transient x;\n uint64 transient y;\n uint64 transient w;\n uint256 transient z;\n\n function f() external returns (uint128, uint64, uint64, uint256) {\n x = 1;\n y = 2;\n w = 3;\n z = 4;\n\n return (x, y, w, z);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// f() -> 1, 2, 3, 4\n" + }, + "transient_state_variable_udvt.sol": { + "content": "type MyInt is int256;\ncontract C {\n MyInt transient public x;\n\n function f() public {\n x = MyInt.wrap(2);\n }\n function g() public returns (MyInt) {\n x = MyInt.wrap(0);\n this.f();\n return x;\n }\n function h() public returns (MyInt) {\n return x;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// x() -> 0\n// g() -> 2\n// h() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_address_code/address_code.sol b/examples/test/semanticTests/various_address_code/address_code.sol new file mode 100644 index 00000000..549512eb --- /dev/null +++ b/examples/test/semanticTests/various_address_code/address_code.sol @@ -0,0 +1,26 @@ +contract C { + bytes public initCode; + + constructor() { + // This should catch problems, but lets also test the case the optimiser is buggy. + assert(address(this).code.length == 0); + initCode = address(this).code; + } + + // To avoid dependency on exact length. + function f() public view returns (bool) { return address(this).code.length > 380; } + function g() public view returns (uint) { return address(0).code.length; } + function h() public view returns (uint) { return address(1).code.length; } +} +// ---- +// constructor() -> +// gas irOptimized: 70760 +// gas irOptimized code: 94600 +// gas legacy: 82428 +// gas legacy code: 153800 +// gas legacyOptimized: 69400 +// gas legacyOptimized code: 79200 +// initCode() -> 0x20, 0 +// f() -> true +// g() -> 0 +// h() -> 0 diff --git a/examples/test/semanticTests/various_address_code/address_code_standard_input.json b/examples/test/semanticTests/various_address_code/address_code_standard_input.json new file mode 100644 index 00000000..82b24b38 --- /dev/null +++ b/examples/test/semanticTests/various_address_code/address_code_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_address_code_complex/address_code_complex.sol b/examples/test/semanticTests/various_address_code_complex/address_code_complex.sol new file mode 100644 index 00000000..f2d21c90 --- /dev/null +++ b/examples/test/semanticTests/various_address_code_complex/address_code_complex.sol @@ -0,0 +1,17 @@ +contract A { + constructor() { + assembly { + // This is only 7 bytes here. + mstore(0, 0x48aa5566000000) + return(0, 32) + } + } +} + +contract C { + function f() public returns (bytes memory) { return address(new A()).code; } + function g() public returns (uint) { return address(new A()).code.length; } +} +// ---- +// f() -> 0x20, 0x20, 0x48aa5566000000 +// g() -> 0x20 diff --git a/examples/test/semanticTests/various_address_code_complex/address_code_complex_standard_input.json b/examples/test/semanticTests/various_address_code_complex/address_code_complex_standard_input.json new file mode 100644 index 00000000..1edd1112 --- /dev/null +++ b/examples/test/semanticTests/various_address_code_complex/address_code_complex_standard_input.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression.sol b/examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression.sol new file mode 100644 index 00000000..110240ce --- /dev/null +++ b/examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression.sol @@ -0,0 +1,9 @@ +contract C { + uint256 constant x = 0x123 + 0x456; + + function f() public returns (uint256) { + return x + 1; + } +} +// ---- +// f() -> 0x57a diff --git a/examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression_standard_input.json b/examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression_standard_input.json new file mode 100644 index 00000000..eb07ea56 --- /dev/null +++ b/examples/test/semanticTests/various_assignment_to_const_var_involving_expression/assignment_to_const_var_involving_expression_standard_input.json @@ -0,0 +1,226 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + }, + "assignment_to_const_var_involving_expression.sol": { + "content": "contract C {\n uint256 constant x = 0x123 + 0x456;\n\n function f() public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f() -> 0x57a\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_balance/balance.sol b/examples/test/semanticTests/various_balance/balance.sol new file mode 100644 index 00000000..8638f409 --- /dev/null +++ b/examples/test/semanticTests/various_balance/balance.sol @@ -0,0 +1,10 @@ +contract test { + constructor() payable {} + + function getBalance() public returns (uint256 balance) { + return address(this).balance; + } +} +// ---- +// constructor(), 23 wei -> +// getBalance() -> 23 diff --git a/examples/test/semanticTests/various_balance/balance_standard_input.json b/examples/test/semanticTests/various_balance/balance_standard_input.json new file mode 100644 index 00000000..1c5a68f0 --- /dev/null +++ b/examples/test/semanticTests/various_balance/balance_standard_input.json @@ -0,0 +1,199 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug.sol b/examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug.sol new file mode 100644 index 00000000..b850ea32 --- /dev/null +++ b/examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug.sol @@ -0,0 +1,16 @@ +contract C { + function f(uint256 x) public returns (uint256 a) { + assembly { + a := byte(x, 31) + } + } + + function g(uint256 x) public returns (uint256 a) { + assembly { + a := byte(31, x) + } + } +} +// ---- +// f(uint256): 2 -> 0 +// g(uint256): 2 -> 2 diff --git a/examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug_standard_input.json b/examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug_standard_input.json new file mode 100644 index 00000000..ca091f94 --- /dev/null +++ b/examples/test/semanticTests/various_byte_optimization_bug/byte_optimization_bug_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_code_access_content/code_access_content.sol b/examples/test/semanticTests/various_code_access_content/code_access_content.sol new file mode 100644 index 00000000..22ceff33 --- /dev/null +++ b/examples/test/semanticTests/various_code_access_content/code_access_content.sol @@ -0,0 +1,45 @@ +contract D { + bytes32 public x; + + constructor() { + bytes32 codeHash; + assembly { + let size := codesize() + codecopy(mload(0x40), 0, size) + codeHash := keccak256(mload(0x40), size) + } + x = codeHash; + } +} + + +contract C { + function testRuntime() public returns (bool) { + D d = new D(); + bytes32 runtimeHash = keccak256(type(D).runtimeCode); + bytes32 otherHash; + uint256 size; + assembly { + size := extcodesize(d) + extcodecopy(d, mload(0x40), 0, size) + otherHash := keccak256(mload(0x40), size) + } + require(size == type(D).runtimeCode.length); + require(runtimeHash == otherHash); + return true; + } + + function testCreation() public returns (bool) { + D d = new D(); + bytes32 creationHash = keccak256(type(D).creationCode); + require(creationHash == d.x()); + return true; + } +} +// ---- +// testRuntime() -> true +// gas legacy: 76575 +// gas legacy code: 23600 +// testCreation() -> true +// gas legacy: 76999 +// gas legacy code: 23600 diff --git a/examples/test/semanticTests/various_code_access_content/code_access_content_standard_input.json b/examples/test/semanticTests/various_code_access_content/code_access_content_standard_input.json new file mode 100644 index 00000000..87ca9241 --- /dev/null +++ b/examples/test/semanticTests/various_code_access_content/code_access_content_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_code_access_create/code_access_create.sol b/examples/test/semanticTests/various_code_access_create/code_access_create.sol new file mode 100644 index 00000000..f5f0b864 --- /dev/null +++ b/examples/test/semanticTests/various_code_access_create/code_access_create.sol @@ -0,0 +1,27 @@ +contract D { + uint256 x; + + constructor() { + x = 7; + } + + function f() public view returns (uint256) { + return x; + } +} + + +contract C { + function test() public returns (uint256) { + bytes memory c = type(D).creationCode; + D d; + assembly { + d := create(0, add(c, 0x20), mload(c)) + } + return d.f(); + } +} +// ---- +// test() -> 7 +// gas legacy: 76647 +// gas legacy code: 24200 diff --git a/examples/test/semanticTests/various_code_access_create/code_access_create_standard_input.json b/examples/test/semanticTests/various_code_access_create/code_access_create_standard_input.json new file mode 100644 index 00000000..c072e718 --- /dev/null +++ b/examples/test/semanticTests/various_code_access_create/code_access_create_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_code_access_padding/code_access_padding.sol b/examples/test/semanticTests/various_code_access_padding/code_access_padding.sol new file mode 100644 index 00000000..831d4bde --- /dev/null +++ b/examples/test/semanticTests/various_code_access_padding/code_access_padding.sol @@ -0,0 +1,18 @@ +contract D { + function f() public pure returns (uint256) { + return 7; + } +} + + +contract C { + function diff() public pure returns (uint256 remainder) { + bytes memory a = type(D).creationCode; + bytes memory b = type(D).runtimeCode; + assembly { + remainder := mod(sub(b, a), 0x20) + } + } +} +// ---- +// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes # diff --git a/examples/test/semanticTests/various_code_access_padding/code_access_padding_standard_input.json b/examples/test/semanticTests/various_code_access_padding/code_access_padding_standard_input.json new file mode 100644 index 00000000..b2ed83ad --- /dev/null +++ b/examples/test/semanticTests/various_code_access_padding/code_access_padding_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_code_access_runtime/code_access_runtime.sol b/examples/test/semanticTests/various_code_access_runtime/code_access_runtime.sol new file mode 100644 index 00000000..10d7c185 --- /dev/null +++ b/examples/test/semanticTests/various_code_access_runtime/code_access_runtime.sol @@ -0,0 +1,27 @@ +contract D { + uint256 x; + + constructor() { + x = 7; + } + + function f() public view returns (uint256) { + return x; + } +} + +contract C { + function test() public returns (uint256) { + D d = new D(); + bytes32 hash; + assembly { hash := extcodehash(d) } + assert(hash == keccak256(type(D).runtimeCode)); + return 42; + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// test() -> 42 +// gas legacy: 76034 +// gas legacy code: 24200 diff --git a/examples/test/semanticTests/various_code_access_runtime/code_access_runtime_standard_input.json b/examples/test/semanticTests/various_code_access_runtime/code_access_runtime_standard_input.json new file mode 100644 index 00000000..975850c7 --- /dev/null +++ b/examples/test/semanticTests/various_code_access_runtime/code_access_runtime_standard_input.json @@ -0,0 +1,217 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_code_length/code_length.sol b/examples/test/semanticTests/various_code_length/code_length.sol new file mode 100644 index 00000000..844a0f65 --- /dev/null +++ b/examples/test/semanticTests/various_code_length/code_length.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-3.0 +contract C { + uint len1; + uint len2; + constructor() { + uint mem_ptr_before; + uint mem_ptr_after; + + assembly { + mem_ptr_before := mload(64) + } + + len1 = address(0).code.length; + + assembly { + mem_ptr_after := mload(64) + } + + // To check that no memory was allocated and written. + assert(mem_ptr_before == mem_ptr_after); + + len2 = address(this).code.length; + + // To check that no memory was allocated and written. + assembly { + mem_ptr_after := mload(64) + } + + assert(mem_ptr_before == mem_ptr_after); + + } + + function f() public view returns (bool r1, bool r2) { + uint mem_ptr_before; + uint mem_ptr_after; + + assembly { + mem_ptr_before := mload(64) + } + + r1 = address(this).code.length > 50; + + assembly { + mem_ptr_after := mload(64) + } + + // To check that no memory was allocated and written. + assert(mem_ptr_before == mem_ptr_after); + + address a = address(0); + r2 = a.code.length == 0; + + // To check that no memory was allocated and written. + assembly { + mem_ptr_after := mload(64) + } + + } +} +// ---- +// constructor() +// gas legacy: 66989 +// gas legacy code: 57800 +// f(): true, true -> true, true diff --git a/examples/test/semanticTests/various_code_length/code_length_standard_input.json b/examples/test/semanticTests/various_code_length/code_length_standard_input.json new file mode 100644 index 00000000..97f121f3 --- /dev/null +++ b/examples/test/semanticTests/various_code_length/code_length_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member.sol b/examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member.sol new file mode 100644 index 00000000..ff883139 --- /dev/null +++ b/examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member.sol @@ -0,0 +1,15 @@ +// Test to see if type.code.length does extcodesize(type) only when type is an address. +struct S { + bytes32 code; + bytes32 another; +} + +contract C { + S s; + + function f() public returns (uint, uint, bool) { + return (s.code.length, s.another.length, address(this).code.length > 50); + } +} +// ---- +// f() -> 0x20, 0x20, true diff --git a/examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member_standard_input.json b/examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member_standard_input.json new file mode 100644 index 00000000..c9699971 --- /dev/null +++ b/examples/test/semanticTests/various_code_length_contract_member/code_length_contract_member_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly.sol b/examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly.sol new file mode 100644 index 00000000..fad0d3e5 --- /dev/null +++ b/examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly.sol @@ -0,0 +1,27 @@ +contract C { + constructor() payable {} + + function f() public returns (uint256 ret) { + assembly { + ret := balance(0) + } + } + function g() public returns (uint256 ret) { + assembly { + ret := balance(1) + } + } + function h() public returns (uint256 ret) { + assembly { + ret := balance(address()) + } + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// constructor(), 23 wei -> +// gas legacy: 100517 +// f() -> 0 +// g() -> 1 +// h() -> 23 diff --git a/examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly_standard_input.json b/examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly_standard_input.json new file mode 100644 index 00000000..0907f0f1 --- /dev/null +++ b/examples/test/semanticTests/various_codebalance_assembly/codebalance_assembly_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_codehash/codehash.sol b/examples/test/semanticTests/various_codehash/codehash.sol new file mode 100644 index 00000000..fa7dab9d --- /dev/null +++ b/examples/test/semanticTests/various_codehash/codehash.sol @@ -0,0 +1,19 @@ +contract C { + function f() public returns (bytes32) { + // non-existent in tests + return address(0).codehash; + } + function g() public returns (bytes32) { + // precompile + return address(0x1).codehash; + } + function h() public returns (bool) { + return address(this).codehash != 0; + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// f() -> 0x0 +// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 +// h() -> true diff --git a/examples/test/semanticTests/various_codehash/codehash_standard_input.json b/examples/test/semanticTests/various_codehash/codehash_standard_input.json new file mode 100644 index 00000000..07620d15 --- /dev/null +++ b/examples/test/semanticTests/various_codehash/codehash_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_codehash_assembly/codehash_assembly.sol b/examples/test/semanticTests/various_codehash_assembly/codehash_assembly.sol new file mode 100644 index 00000000..fe2210fa --- /dev/null +++ b/examples/test/semanticTests/various_codehash_assembly/codehash_assembly.sol @@ -0,0 +1,23 @@ +contract C { + function f() public returns (bytes32 ret) { + assembly { + ret := extcodehash(0) + } + } + function g() public returns (bytes32 ret) { + assembly { + ret := extcodehash(1) + } + } + function h() public returns (bool ret) { + assembly { + ret := iszero(iszero(extcodehash(address()))) + } + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// f() -> 0 +// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 +// h() -> true diff --git a/examples/test/semanticTests/various_codehash_assembly/codehash_assembly_standard_input.json b/examples/test/semanticTests/various_codehash_assembly/codehash_assembly_standard_input.json new file mode 100644 index 00000000..9ca70d99 --- /dev/null +++ b/examples/test/semanticTests/various_codehash_assembly/codehash_assembly_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies.sol b/examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies.sol new file mode 100644 index 00000000..0ebf772f --- /dev/null +++ b/examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies.sol @@ -0,0 +1,20 @@ +contract A { + function f() public { + new B(); + } +} + + +contract B { + function f() public {} +} + + +contract C { + function f() public { + new B(); + } +} +// ---- +// constructor() -> +// gas irOptimized: 100415 diff --git a/examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies_standard_input.json b/examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies_standard_input.json new file mode 100644 index 00000000..1b6789a9 --- /dev/null +++ b/examples/test/semanticTests/various_contract_binary_dependencies/contract_binary_dependencies_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack.sol b/examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack.sol new file mode 100644 index 00000000..bc16bacb --- /dev/null +++ b/examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack.sol @@ -0,0 +1,12 @@ +contract C { + function f() public returns (uint256 r) { + uint256; + uint256; + uint256; + uint256; + int256 x = -7; + return uint256(x); + } +} +// ---- +// f() -> -7 diff --git a/examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack_standard_input.json b/examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack_standard_input.json new file mode 100644 index 00000000..79790c0e --- /dev/null +++ b/examples/test/semanticTests/various_crazy_elementary_typenames_on_stack/crazy_elementary_typenames_on_stack_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_create_calldata/create_calldata.sol b/examples/test/semanticTests/various_create_calldata/create_calldata.sol new file mode 100644 index 00000000..a5f61d2d --- /dev/null +++ b/examples/test/semanticTests/various_create_calldata/create_calldata.sol @@ -0,0 +1,17 @@ +contract C { + bytes public s; + constructor(uint256 x) { + // Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments. + s = msg.data; + assert(msg.data.length == 0); + } +} +// ---- +// constructor(): 42 -> +// gas irOptimized: 68239 +// gas irOptimized code: 69000 +// gas legacy: 78076 +// gas legacy code: 90200 +// gas legacyOptimized: 68321 +// gas legacyOptimized code: 64600 +// s() -> 0x20, 0 diff --git a/examples/test/semanticTests/various_create_calldata/create_calldata_standard_input.json b/examples/test/semanticTests/various_create_calldata/create_calldata_standard_input.json new file mode 100644 index 00000000..3ce16e17 --- /dev/null +++ b/examples/test/semanticTests/various_create_calldata/create_calldata_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_create_random/create_random.sol b/examples/test/semanticTests/various_create_random/create_random.sol new file mode 100644 index 00000000..676ec32a --- /dev/null +++ b/examples/test/semanticTests/various_create_random/create_random.sol @@ -0,0 +1,39 @@ +contract C { + function addr() external returns (address) { + return address(this); + } + + function testRunner() external returns (address a1, address a2) { + assembly { + // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid + // instability due to metadata changes. + let initcode := hex"60016000f3" + mstore(0, initcode) + + a1 := create(0, 0, 5) + a2 := create2(0, 0, 5, address()) + } + } + + function testCalc() external returns (address a1, address a2) { + a1 = calculateCreate(address(this), 1); + a2 = calculateCreate2(address(this), keccak256(hex"60016000f3"), bytes32(uint256(uint160(address(this))))); + } + + function calculateCreate(address from, uint256 nonce) private pure returns (address) { + assert(nonce <= 127); + bytes memory data = + bytes.concat(hex"d694", bytes20(uint160(from)), nonce == 0 ? bytes1(hex"80") : bytes1(uint8(nonce))); + return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits + } + + function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) { + return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash))))); + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d +// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d diff --git a/examples/test/semanticTests/various_create_random/create_random_standard_input.json b/examples/test/semanticTests/various_create_random/create_random_standard_input.json new file mode 100644 index 00000000..57323207 --- /dev/null +++ b/examples/test/semanticTests/various_create_random/create_random_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_cross_contract_types/cross_contract_types.sol b/examples/test/semanticTests/various_cross_contract_types/cross_contract_types.sol new file mode 100644 index 00000000..9c7728a0 --- /dev/null +++ b/examples/test/semanticTests/various_cross_contract_types/cross_contract_types.sol @@ -0,0 +1,16 @@ +contract Lib { + struct S { + uint256 a; + uint256 b; + } +} + + +contract Test { + function f() public returns (uint256 r) { + Lib.S memory x = Lib.S({a: 2, b: 3}); + r = x.b; + } +} +// ---- +// f() -> 3 diff --git a/examples/test/semanticTests/various_cross_contract_types/cross_contract_types_standard_input.json b/examples/test/semanticTests/various_cross_contract_types/cross_contract_types_standard_input.json new file mode 100644 index 00000000..57678215 --- /dev/null +++ b/examples/test/semanticTests/various_cross_contract_types/cross_contract_types_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_decayed_tuple/decayed_tuple.sol b/examples/test/semanticTests/various_decayed_tuple/decayed_tuple.sol new file mode 100644 index 00000000..799da348 --- /dev/null +++ b/examples/test/semanticTests/various_decayed_tuple/decayed_tuple.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (uint256) { + uint256 x = 1; + (x) = 2; + return x; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/various_decayed_tuple/decayed_tuple_standard_input.json b/examples/test/semanticTests/various_decayed_tuple/decayed_tuple_standard_input.json new file mode 100644 index 00000000..3151b1f1 --- /dev/null +++ b/examples/test/semanticTests/various_decayed_tuple/decayed_tuple_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment.sol b/examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment.sol new file mode 100644 index 00000000..a961870e --- /dev/null +++ b/examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment.sol @@ -0,0 +1,38 @@ +contract C { + uint256 x = 7; + bytes data; + uint256[] y; + uint256[] arrayData; + + function returnsArray() public returns (uint256[] memory) { + arrayData = new uint256[](9); + arrayData[2] = 5; + arrayData[7] = 4; + return arrayData; + } + + function f(bytes memory s) public returns (uint256) { + uint256 loc; + uint256[] memory memArray; + (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2); + if (loc != 8) return 1; + if (x != 4) return 2; + if (y.length != 9) return 3; + if (y[2] != 5) return 4; + if (y[7] != 4) return 5; + if (data.length != s.length) return 6; + if (data[3] != s[3]) return 7; + if (arrayData[3] != 2) return 8; + (memArray, loc) = (arrayData, 3); + if (loc != 3) return 9; + if (memArray.length != arrayData.length) return 10; + bytes memory memBytes; + (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415); + if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11; + } +} +// ---- +// f(bytes): 0x20, 0x5, "abcde" -> 0 +// gas irOptimized: 242027 +// gas legacy: 243281 +// gas legacyOptimized: 242392 diff --git a/examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment_standard_input.json b/examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment_standard_input.json new file mode 100644 index 00000000..5125ddc6 --- /dev/null +++ b/examples/test/semanticTests/various_destructuring_assignment/destructuring_assignment_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient.sol b/examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient.sol new file mode 100644 index 00000000..399cbd02 --- /dev/null +++ b/examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient.sol @@ -0,0 +1,51 @@ +contract B { + uint256 transient public value; + + function setValue(uint256 v) public { + value += v; + } +} + +contract A { + uint256 transient public value; + + function delegateSetValue(address otherContract, uint256 v) public { + (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature("setValue(uint256)", v)); + require(success); + } + function callSetValue(address otherContract, uint256 v) public { + (bool success, ) = otherContract.call(abi.encodeWithSignature("setValue(uint256)", v)); + require(success); + } + function staticSetValue(address otherContract, uint256 v) view public returns (bool) { + (bool success, ) = otherContract.staticcall(abi.encodeWithSignature("setValue(uint256)", v)); + return success; + } +} + +contract Test { + A a = new A(); + B b = new B(); + + function testDelegate() public returns (uint256, uint256) { + a.delegateSetValue(address(b), 7); + return (a.value(), b.value()); + } + function testCall() public returns (uint256, uint256) { + a.callSetValue(address(b), 8); + return (a.value(), b.value()); + } + function testStatic() view public returns (bool) { + return a.staticSetValue(address(b), 0); + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// testDelegate() -> 7, 0 +// testCall() -> 0, 8 +// testStatic() -> false +// gas irOptimized: 96900694 +// gas legacy: 96901136 +// gas legacyOptimized: 96900725 diff --git a/examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient_standard_input.json b/examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient_standard_input.json new file mode 100644 index 00000000..20c38c7f --- /dev/null +++ b/examples/test/semanticTests/various_different_call_type_transient/different_call_type_transient_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter.sol b/examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter.sol new file mode 100644 index 00000000..71eb0077 --- /dev/null +++ b/examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter.sol @@ -0,0 +1,7 @@ +contract test { + function f(uint256 k) public returns (uint256) { + return k; + } +} +// ---- +// f(uint256): 9 -> 9 diff --git a/examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter_standard_input.json b/examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter_standard_input.json new file mode 100644 index 00000000..657c5ac9 --- /dev/null +++ b/examples/test/semanticTests/various_empty_name_return_parameter/empty_name_return_parameter_standard_input.json @@ -0,0 +1,235 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + }, + "assignment_to_const_var_involving_expression.sol": { + "content": "contract C {\n uint256 constant x = 0x123 + 0x456;\n\n function f() public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f() -> 0x57a\n" + }, + "storage_string_as_mapping_key_without_variable.sol": { + "content": "contract Test {\n mapping(string => uint256) data;\n\n function f() public returns (uint256) {\n data[\"abc\"] = 2;\n return data[\"abc\"];\n }\n}\n// ----\n// f() -> 2\n" + }, + "skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bool[] b;\n }\n\n function f() public returns (uint256, bool[][2] memory, S[2] memory, uint256) {\n return (\n 5,\n [new bool[](1), new bool[](2)],\n [S(new bool[](2)), S(new bool[](5))],\n 6\n );\n }\n\n function g() public returns (uint256, uint256) {\n (uint256 a, , , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 5, 6\n" + }, + "empty_name_return_parameter.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256) {\n return k;\n }\n}\n// ----\n// f(uint256): 9 -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_erc20/erc20.sol b/examples/test/semanticTests/various_erc20/erc20.sol new file mode 100644 index 00000000..1cc77270 --- /dev/null +++ b/examples/test/semanticTests/various_erc20/erc20.sol @@ -0,0 +1,131 @@ +pragma solidity >=0.4.0 <0.9.0; + +contract ERC20 { + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + mapping (address => uint256) private _balances; + mapping (address => mapping (address => uint256)) private _allowances; + uint256 private _totalSupply; + + constructor() { + _mint(msg.sender, 20); + } + + function totalSupply() public view returns (uint256) { + return _totalSupply; + } + + function balanceOf(address owner) public view returns (uint256) { + return _balances[owner]; + } + + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; + } + + function transfer(address to, uint256 value) public returns (bool) { + _transfer(msg.sender, to, value); + return true; + } + + function approve(address spender, uint256 value) public returns (bool) { + _approve(msg.sender, spender, value); + return true; + } + + function transferFrom(address from, address to, uint256 value) public returns (bool) { + _transfer(from, to, value); + // The subtraction here will revert on overflow. + _approve(from, msg.sender, _allowances[from][msg.sender] - value); + return true; + } + + function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { + // The addition here will revert on overflow. + _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue); + return true; + } + + function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { + // The subtraction here will revert on overflow. + _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue); + return true; + } + + function _transfer(address from, address to, uint256 value) internal { + require(to != address(0), "ERC20: transfer to the zero address"); + + // The subtraction and addition here will revert on overflow. + _balances[from] = _balances[from] - value; + _balances[to] = _balances[to] + value; + emit Transfer(from, to, value); + } + + function _mint(address account, uint256 value) internal { + require(account != address(0), "ERC20: mint to the zero address"); + + // The additions here will revert on overflow. + _totalSupply = _totalSupply + value; + _balances[account] = _balances[account] + value; + emit Transfer(address(0), account, value); + } + + function _burn(address account, uint256 value) internal { + require(account != address(0), "ERC20: burn from the zero address"); + + // The subtractions here will revert on overflow. + _totalSupply = _totalSupply - value; + _balances[account] = _balances[account] - value; + emit Transfer(account, address(0), value); + } + + function _approve(address owner, address spender, uint256 value) internal { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = value; + emit Approval(owner, spender, value); + } + + function _burnFrom(address account, uint256 value) internal { + _burn(account, value); + _approve(account, msg.sender, _allowances[account][msg.sender] - value); + } +} +// ---- +// constructor() +// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14 +// gas irOptimized: 121632 +// gas irOptimized code: 236800 +// gas legacy: 159957 +// gas legacy code: 647600 +// gas legacyOptimized: 126934 +// gas legacyOptimized code: 282000 +// totalSupply() -> 20 +// gas irOptimized: 23415 +// gas legacy: 23524 +// gas legacyOptimized: 23368 +// transfer(address,uint256): 2, 5 -> true +// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05 +// gas irOptimized: 48471 +// gas legacy: 49317 +// gas legacyOptimized: 48491 +// decreaseAllowance(address,uint256): 2, 0 -> true +// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00 +// gas irOptimized: 26275 +// gas legacy: 27012 +// gas legacyOptimized: 26275 +// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11 +// gas irOptimized: 24042 +// gas legacy: 24467 +// gas legacyOptimized: 24056 +// transfer(address,uint256): 2, 14 -> true +// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e +// gas irOptimized: 28571 +// gas legacy: 29417 +// gas legacyOptimized: 28591 +// transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11 +// gas irOptimized: 24071 +// gas legacy: 24453 +// gas legacyOptimized: 24053 diff --git a/examples/test/semanticTests/various_erc20/erc20_standard_input.json b/examples/test/semanticTests/various_erc20/erc20_standard_input.json new file mode 100644 index 00000000..311e70a0 --- /dev/null +++ b/examples/test/semanticTests/various_erc20/erc20_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls.sol b/examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls.sol new file mode 100644 index 00000000..84e4d36d --- /dev/null +++ b/examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls.sol @@ -0,0 +1,29 @@ +contract C1 { + C1 public bla; + + constructor(C1 x) { + bla = x; + } +} + + +contract C { + function test() public returns (C1 x, C1 y) { + C1 c = new C1(C1(address(9))); + x = c.bla(); + y = this.t1(C1(address(7))); + } + + function t1(C1 a) public returns (C1) { + return a; + } + + function t2() public returns (C1) { + return C1(address(9)); + } +} +// ---- +// test() -> 9, 7 +// gas legacy: 80314 +// gas legacy code: 47400 +// t2() -> 9 diff --git a/examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls_standard_input.json b/examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls_standard_input.json new file mode 100644 index 00000000..29ed7e60 --- /dev/null +++ b/examples/test/semanticTests/various_external_types_in_calls/external_types_in_calls_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests.sol b/examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests.sol new file mode 100644 index 00000000..174fb993 --- /dev/null +++ b/examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests.sol @@ -0,0 +1,9 @@ +contract test { + function f() public returns (bool) { + int256 x = -2**255; + unchecked { assert(-x == x); } + return true; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests_standard_input.json b/examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests_standard_input.json new file mode 100644 index 00000000..2798a4dc --- /dev/null +++ b/examples/test/semanticTests/various_flipping_sign_tests/flipping_sign_tests_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease.sol b/examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease.sol new file mode 100644 index 00000000..ab730274 --- /dev/null +++ b/examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease.sol @@ -0,0 +1,19 @@ +contract C { + uint256 v; + + function f() public returns (bool) { + uint256 startGas = gasleft(); + v++; + assert(startGas > gasleft()); + return true; + } + + function g() public returns (bool) { + uint256 startGas = gasleft(); + assert(startGas > gasleft()); + return true; + } +} +// ---- +// f() -> true +// g() -> true diff --git a/examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease_standard_input.json b/examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease_standard_input.json new file mode 100644 index 00000000..76731c22 --- /dev/null +++ b/examples/test/semanticTests/various_gasleft_decrease/gasleft_decrease_standard_input.json @@ -0,0 +1,193 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution.sol b/examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution.sol new file mode 100644 index 00000000..280bc496 --- /dev/null +++ b/examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution.sol @@ -0,0 +1,11 @@ +contract C { + function gasleft() public returns (uint256) { + return 0; + } + + function f() public returns (uint256) { + return gasleft(); + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution_standard_input.json b/examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution_standard_input.json new file mode 100644 index 00000000..7e4f2730 --- /dev/null +++ b/examples/test/semanticTests/various_gasleft_shadow_resolution/gasleft_shadow_resolution_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_inline_member_init/inline_member_init.sol b/examples/test/semanticTests/various_inline_member_init/inline_member_init.sol new file mode 100644 index 00000000..5c48b5d7 --- /dev/null +++ b/examples/test/semanticTests/various_inline_member_init/inline_member_init.sol @@ -0,0 +1,18 @@ +contract test { + constructor() { + m_b = 6; + m_c = 8; + } + + uint256 m_a = 5; + uint256 m_b; + uint256 m_c = 7; + + function get() public returns (uint256 a, uint256 b, uint256 c) { + a = m_a; + b = m_b; + c = m_c; + } +} +// ---- +// get() -> 5, 6, 8 diff --git a/examples/test/semanticTests/various_inline_member_init/inline_member_init_standard_input.json b/examples/test/semanticTests/various_inline_member_init/inline_member_init_standard_input.json new file mode 100644 index 00000000..0d74d3bd --- /dev/null +++ b/examples/test/semanticTests/various_inline_member_init/inline_member_init_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence.sol b/examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence.sol new file mode 100644 index 00000000..b440b35a --- /dev/null +++ b/examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence.sol @@ -0,0 +1,23 @@ +contract Base { + constructor() {} + + uint256 m_base = 5; + + function getBMember() public returns (uint256 i) { + return m_base; + } +} + + +contract Derived is Base { + constructor() {} + + uint256 m_derived = 6; + + function getDMember() public returns (uint256 i) { + return m_derived; + } +} +// ---- +// getBMember() -> 5 +// getDMember() -> 6 diff --git a/examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence_standard_input.json b/examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence_standard_input.json new file mode 100644 index 00000000..0ffb7bad --- /dev/null +++ b/examples/test/semanticTests/various_inline_member_init_inheritence/inline_member_init_inheritence_standard_input.json @@ -0,0 +1,208 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers.sol b/examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers.sol new file mode 100644 index 00000000..e85a38dd --- /dev/null +++ b/examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers.sol @@ -0,0 +1,8 @@ +contract c { + function f() public returns (int8) { + int8[5] memory foo3 = [int8(1), -1, 0, 0, 0]; + return foo3[0]; + } +} +// ---- +// f() -> 1 diff --git a/examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers_standard_input.json b/examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers_standard_input.json new file mode 100644 index 00000000..1a40082c --- /dev/null +++ b/examples/test/semanticTests/various_inline_tuple_with_rational_numbers/inline_tuple_with_rational_numbers_standard_input.json @@ -0,0 +1,220 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct.sol b/examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct.sol new file mode 100644 index 00000000..d797ab9c --- /dev/null +++ b/examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct.sol @@ -0,0 +1,18 @@ +// A long time ago, some opcodes were renamed, which involved the opcodes +// "iszero" and "not". +contract C { + function f() public returns (bool) { + bytes32 x = bytes32(uint256(1)); + assembly { + x := not(x) + } + if (x != ~bytes32(uint256(1))) return false; + assembly { + x := iszero(x) + } + if (x != bytes32(0)) return false; + return true; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct_standard_input.json b/examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct_standard_input.json new file mode 100644 index 00000000..2a8afc5e --- /dev/null +++ b/examples/test/semanticTests/various_iszero_bnot_correct/iszero_bnot_correct_standard_input.json @@ -0,0 +1,202 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_literal_empty_string/literal_empty_string.sol b/examples/test/semanticTests/various_literal_empty_string/literal_empty_string.sol new file mode 100644 index 00000000..44154fa5 --- /dev/null +++ b/examples/test/semanticTests/various_literal_empty_string/literal_empty_string.sol @@ -0,0 +1,19 @@ +contract C { + bytes32 public x; + uint256 public a; + + function f(bytes32 _x, uint256 _a) public { + x = _x; + a = _a; + } + + function g() public { + this.f("", 2); + } +} +// ---- +// x() -> 0 +// a() -> 0 +// g() -> +// x() -> 0 +// a() -> 2 diff --git a/examples/test/semanticTests/various_literal_empty_string/literal_empty_string_standard_input.json b/examples/test/semanticTests/various_literal_empty_string/literal_empty_string_standard_input.json new file mode 100644 index 00000000..9e42d4cf --- /dev/null +++ b/examples/test/semanticTests/various_literal_empty_string/literal_empty_string_standard_input.json @@ -0,0 +1,241 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + }, + "assignment_to_const_var_involving_expression.sol": { + "content": "contract C {\n uint256 constant x = 0x123 + 0x456;\n\n function f() public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f() -> 0x57a\n" + }, + "storage_string_as_mapping_key_without_variable.sol": { + "content": "contract Test {\n mapping(string => uint256) data;\n\n function f() public returns (uint256) {\n data[\"abc\"] = 2;\n return data[\"abc\"];\n }\n}\n// ----\n// f() -> 2\n" + }, + "skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bool[] b;\n }\n\n function f() public returns (uint256, bool[][2] memory, S[2] memory, uint256) {\n return (\n 5,\n [new bool[](1), new bool[](2)],\n [S(new bool[](2)), S(new bool[](5))],\n 6\n );\n }\n\n function g() public returns (uint256, uint256) {\n (uint256 a, , , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 5, 6\n" + }, + "empty_name_return_parameter.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256) {\n return k;\n }\n}\n// ----\n// f(uint256): 9 -> 9\n" + }, + "tuples.sol": { + "content": "contract C {\n uint256[] data;\n uint256[] m_c;\n\n function g() internal returns (uint256 a, uint256 b, uint256[] storage c) {\n return (1, 2, data);\n }\n\n function h() external returns (uint256 a, uint256 b) {\n return (5, 6);\n }\n\n function f() public returns (uint256) {\n data.push(3);\n uint256 a;\n uint256 b;\n (a, b) = this.h();\n if (a != 5 || b != 6) return 1;\n uint256[] storage c = m_c;\n (a, b, c) = g();\n if (a != 1 || b != 2 || c[0] != 3) return 2;\n (a, b) = (b, a);\n if (a != 2 || b != 1) return 3;\n (a, , b, , ) = (8, 9, 10, 11, 12);\n if (a != 8 || b != 10) return 4;\n }\n}\n// ----\n// f() -> 0\n" + }, + "literal_empty_string.sol": { + "content": "contract C {\n bytes32 public x;\n uint256 public a;\n\n function f(bytes32 _x, uint256 _a) public {\n x = _x;\n a = _a;\n }\n\n function g() public {\n this.f(\"\", 2);\n }\n}\n// ----\n// x() -> 0\n// a() -> 0\n// g() ->\n// x() -> 0\n// a() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_many_subassemblies/many_subassemblies.sol b/examples/test/semanticTests/various_many_subassemblies/many_subassemblies.sol new file mode 100644 index 00000000..b270c700 --- /dev/null +++ b/examples/test/semanticTests/various_many_subassemblies/many_subassemblies.sol @@ -0,0 +1,38 @@ +contract C0 {} +contract C1 {} +contract C2 {} +contract C3 {} +contract C4 {} +contract C5 {} +contract C6 {} +contract C7 {} +contract C8 {} +contract C9 {} +contract C10 {} + +contract D { + function run() public { + // This is primarily meant to test assembly import via --import-asm-json. + // The exported JSON will fail the reimport unless the subassembly indices are parsed + // correctly - as hex numbers. + new C0(); + new C1(); + new C2(); + new C3(); + new C4(); + new C5(); + new C6(); + new C7(); + new C8(); + new C9(); + new C10(); + } +} +// ---- +// run() -> +// gas irOptimized: 374934 +// gas irOptimized code: 6600 +// gas legacy: 375119 +// gas legacy code: 17600 +// gas legacyOptimized: 375119 +// gas legacyOptimized code: 17600 diff --git a/examples/test/semanticTests/various_many_subassemblies/many_subassemblies_standard_input.json b/examples/test/semanticTests/various_many_subassemblies/many_subassemblies_standard_input.json new file mode 100644 index 00000000..cfe537ba --- /dev/null +++ b/examples/test/semanticTests/various_many_subassemblies/many_subassemblies_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_memory_overwrite/memory_overwrite.sol b/examples/test/semanticTests/various_memory_overwrite/memory_overwrite.sol new file mode 100644 index 00000000..3ab16a3e --- /dev/null +++ b/examples/test/semanticTests/various_memory_overwrite/memory_overwrite.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (bytes memory x) { + x = "12345"; + x[3] = 0x61; + x[0] = 0x62; + } +} +// ---- +// f() -> 0x20, 5, "b23a5" diff --git a/examples/test/semanticTests/various_memory_overwrite/memory_overwrite_standard_input.json b/examples/test/semanticTests/various_memory_overwrite/memory_overwrite_standard_input.json new file mode 100644 index 00000000..fb7d4f82 --- /dev/null +++ b/examples/test/semanticTests/various_memory_overwrite/memory_overwrite_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_multi_modifiers/multi_modifiers.sol b/examples/test/semanticTests/various_multi_modifiers/multi_modifiers.sol new file mode 100644 index 00000000..07f6c038 --- /dev/null +++ b/examples/test/semanticTests/various_multi_modifiers/multi_modifiers.sol @@ -0,0 +1,23 @@ +// This triggered a bug in some version because the variable in the modifier was not +// unregistered correctly. +contract C { + uint256 public x; + modifier m1 { + address a1 = msg.sender; + x++; + _; + } + + function f1() public m1() { + x += 7; + } + + function f2() public m1() { + x += 3; + } +} +// ---- +// f1() -> +// x() -> 0x08 +// f2() -> +// x() -> 0x0c diff --git a/examples/test/semanticTests/various_multi_modifiers/multi_modifiers_standard_input.json b/examples/test/semanticTests/various_multi_modifiers/multi_modifiers_standard_input.json new file mode 100644 index 00000000..3076ef07 --- /dev/null +++ b/examples/test/semanticTests/various_multi_modifiers/multi_modifiers_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration.sol b/examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration.sol new file mode 100644 index 00000000..de4ecdbe --- /dev/null +++ b/examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration.sol @@ -0,0 +1,46 @@ +contract C { + function g() public returns (uint256 a, uint256 b, uint256 c) { + a = 1; + b = 2; + c = 3; + } + + function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) { + a = 1; + b = 2; + c = 3; + d = 4; + } + + function f1() public returns (bool) { + (uint256 x, uint256 y, uint256 z) = g(); + if (x != 1 || y != 2 || z != 3) return false; + (, uint256 a, ) = g(); + if (a != 2) return false; + (uint256 b, , ) = g(); + if (b != 1) return false; + (, , uint256 c) = g(); + if (c != 3) return false; + return true; + } + + function f2() public returns (bool) { + (uint256 a1, , uint256 a3, ) = h(); + if (a1 != 1 || a3 != 3) return false; + (uint256 b1, uint256 b2, , ) = h(); + if (b1 != 1 || b2 != 2) return false; + (, uint256 c2, uint256 c3, ) = h(); + if (c2 != 2 || c3 != 3) return false; + (, , uint256 d3, uint256 d4) = h(); + if (d3 != 3 || d4 != 4) return false; + (uint256 e1, , uint256 e3, uint256 e4) = h(); + if (e1 != 1 || e3 != 3 || e4 != 4) return false; + return true; + } + + function f() public returns (bool) { + return f1() && f2(); + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration_standard_input.json b/examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration_standard_input.json new file mode 100644 index 00000000..442b38d0 --- /dev/null +++ b/examples/test/semanticTests/various_multi_variable_declaration/multi_variable_declaration_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_negative_stack_height/negative_stack_height.sol b/examples/test/semanticTests/various_negative_stack_height/negative_stack_height.sol new file mode 100644 index 00000000..44fd0089 --- /dev/null +++ b/examples/test/semanticTests/various_negative_stack_height/negative_stack_height.sol @@ -0,0 +1,71 @@ +contract C { + mapping(uint256 => Invoice) public invoices; + struct Invoice { + uint256 AID; + bool Aboola; + bool Aboolc; + bool exists; + } + + function nredit(uint256 startindex) + public + pure + returns ( + uint256[500] memory CIDs, + uint256[500] memory dates, + uint256[500] memory RIDs, + bool[500] memory Cboolas, + uint256[500] memory amounts + ) + {} + + function return500InvoicesByDates( + uint256 begindate, + uint256 enddate, + uint256 startindex + ) + public + view + returns ( + uint256[500] memory AIDs, + bool[500] memory Aboolas, + uint256[500] memory dates, + bytes32[3][500] memory Abytesas, + bytes32[3][500] memory bytesbs, + bytes32[2][500] memory bytescs, + uint256[500] memory amounts, + bool[500] memory Aboolbs, + bool[500] memory Aboolcs + ) + {} + + function return500PaymentsByDates( + uint256 begindate, + uint256 enddate, + uint256 startindex + ) + public + view + returns ( + uint256[500] memory BIDs, + uint256[500] memory dates, + uint256[500] memory RIDs, + bool[500] memory Bboolas, + bytes32[3][500] memory bytesbs, + bytes32[2][500] memory bytescs, + uint256[500] memory amounts, + bool[500] memory Bboolbs + ) + {} +} + +// via yul disabled because of stack issues. + +// ==== +// compileViaYul: false +// ---- +// constructor() -> +// gas legacy: 92268 +// gas legacy code: 483000 +// gas legacyOptimized: 75022 +// gas legacyOptimized code: 270000 diff --git a/examples/test/semanticTests/various_negative_stack_height/negative_stack_height_standard_input.json b/examples/test/semanticTests/various_negative_stack_height/negative_stack_height_standard_input.json new file mode 100644 index 00000000..ed9b1556 --- /dev/null +++ b/examples/test/semanticTests/various_negative_stack_height/negative_stack_height_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct.sol b/examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct.sol new file mode 100644 index 00000000..b1124132 --- /dev/null +++ b/examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct.sol @@ -0,0 +1,25 @@ +pragma abicoder v2; + + +contract C { + struct S1 { + uint256 a; + uint256 b; + } + struct S2 { + uint256 a; + uint256 b; + S1 s; + uint256 c; + } + + function f(S2 calldata s) + external + pure + returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c) + { + return (s.a, s.b, s.s.a, s.s.b, s.c); + } +} +// ---- +// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5 diff --git a/examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct_standard_input.json b/examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct_standard_input.json new file mode 100644 index 00000000..39c0ab27 --- /dev/null +++ b/examples/test/semanticTests/various_nested_calldata_struct/nested_calldata_struct_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory.sol b/examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory.sol new file mode 100644 index 00000000..25cd645e --- /dev/null +++ b/examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory.sol @@ -0,0 +1,26 @@ +pragma abicoder v2; + + +contract C { + struct S1 { + uint256 a; + uint256 b; + } + struct S2 { + uint256 a; + uint256 b; + S1 s; + uint256 c; + } + + function f(S2 calldata s) + external + pure + returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c) + { + S2 memory m = s; + return (m.a, m.b, m.s.a, m.s.b, m.c); + } +} +// ---- +// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5 diff --git a/examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory_standard_input.json b/examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory_standard_input.json new file mode 100644 index 00000000..f1f39cb3 --- /dev/null +++ b/examples/test/semanticTests/various_nested_calldata_struct_to_memory/nested_calldata_struct_to_memory_standard_input.json @@ -0,0 +1,196 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed.sol b/examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed.sol new file mode 100644 index 00000000..4c0d7114 --- /dev/null +++ b/examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed.sol @@ -0,0 +1,9 @@ +contract test { + int8 public x = 2; + int8 public y = 127; + int16 public q = 250; +} +// ---- +// x() -> 2 +// y() -> 127 +// q() -> 250 diff --git a/examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed_standard_input.json b/examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed_standard_input.json new file mode 100644 index 00000000..f9aee96f --- /dev/null +++ b/examples/test/semanticTests/various_positive_integers_to_signed/positive_integers_to_signed_standard_input.json @@ -0,0 +1,190 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun.sol b/examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun.sol new file mode 100644 index 00000000..4cb5c8c7 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun.sol @@ -0,0 +1,91 @@ +contract C { + constructor() payable {} + + function terminate() external { + // NOTE: The contract `c` should still exist in the test below + // when the call to selfdestruct is executed in a transaction + // different from the one in which the contract was created. + // However, it should still send all Ether in `c` to the beneficiary. + selfdestruct(payable(msg.sender)); + assert(false); + } +} + +contract D { + C public c; + + constructor() payable {} + + function deploy_create() public payable { + c = new C{value: 1 ether}(); + } + + function deploy_create2() public payable { + c = new C{value: 1 ether, salt: hex"1234"}(); + } + + function terminate() public { + // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the + // previous selfdestruct was performed in a different transaction, since the contract will still exists. + c.terminate(); + } + + function test_create_and_terminate() public { + deploy_create(); + assert(exists()); + test_balance_after_create(); + terminate(); + test_balance_after_selfdestruct(); + } + + function test_create2_and_terminate() public { + deploy_create2(); + assert(exists()); + test_balance_after_create(); + terminate(); + test_balance_after_selfdestruct(); + } + + function test_balance_after_create() public view { + assert(address(this).balance == 0); + assert(address(c).balance == 1 ether); + } + + function test_balance_after_selfdestruct() public view { + assert(address(this).balance == 1 ether); + assert(address(c).balance == 0); + } + + function exists() public view returns (bool) { + return address(c).code.length != 0; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 67028 +// gas irOptimized code: 175400 +// gas legacy: 76227 +// gas legacy code: 298200 +// gas legacyOptimized: 66516 +// gas legacyOptimized code: 168000 +// exists() -> false +// test_create_and_terminate() -> +// exists() -> false +// terminate() -> FAILURE +// deploy_create() -> +// test_balance_after_create() -> +// exists() -> true +// terminate() -> +// test_balance_after_selfdestruct() -> +// exists() -> true +// test_create2_and_terminate() -> +// exists() -> false +// deploy_create2() -> +// test_balance_after_create() -> +// exists() -> true +// terminate() -> +// test_balance_after_selfdestruct() -> +// exists() -> true +// terminate() -> diff --git a/examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun_standard_input.json b/examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun_standard_input.json new file mode 100644 index 00000000..3d3c6182 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_post_cancun/selfdestruct_post_cancun_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries.sol b/examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries.sol new file mode 100644 index 00000000..a5826491 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries.sol @@ -0,0 +1,70 @@ +contract C { + constructor() payable {} + function terminate(address _beneficiary) public { + selfdestruct(payable(_beneficiary)); + assert(false); + } +} + +contract D { + address account1 = payable(0x1111111111111111111111111111111111111111); + address account2 = payable(0x2222222222222222222222222222222222222222); + C public c; + + constructor() payable {} + + function deploy() public payable { + c = new C{value: 1 ether}(); + } + + function terminate(address _beneficiary) public { + c.terminate(_beneficiary); + } + + function test_deploy_and_terminate_twice() public { + deploy(); + terminate(account1); + terminate(account2); + } + + function exists() public view returns (bool) { + return address(c).code.length != 0; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// constructor(), 2 ether -> +// gas irOptimized: 108104 +// gas irOptimized code: 119200 +// gas legacy: 120439 +// gas legacy code: 253800 +// gas legacyOptimized: 109015 +// gas legacyOptimized code: 130800 +// balance: 0x1111111111111111111111111111111111111111 -> 0 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 2000000000000000000 +// exists() -> false +// test_deploy_and_terminate_twice() -> +// gas irOptimized: 121395 +// gas irOptimized code: 14000 +// gas legacy: 122386 +// gas legacy code: 43200 +// gas legacyOptimized: 121596 +// gas legacyOptimized code: 22800 +// exists() -> false +// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 1000000000000000000 +// deploy() -> +// gas legacy: 58491 +// gas legacy code: 43200 +// exists() -> true +// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 0 +// terminate(address): 0x1111111111111111111111111111111111111111 -> +// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 0 +// exists() -> true diff --git a/examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries_standard_input.json b/examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries_standard_input.json new file mode 100644 index 00000000..82145e7b --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_post_cancun_multiple_beneficiaries/selfdestruct_post_cancun_multiple_beneficiaries_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy.sol b/examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy.sol new file mode 100644 index 00000000..dd550d31 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy.sol @@ -0,0 +1,111 @@ +contract Factory { + event Deployed(address, bytes32); + + function deploy(bytes32 _salt) external payable returns (address implAddr) { + // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code + // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized. + //contract C { + // constructor() payable {} + // function terminate() external { + // selfdestruct(payable(msg.sender)); + // } + //} + bytes memory initCode = + hex"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0" + hex"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f" + hex"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf" + hex"ced7eff135da3556db4bd841aa64736f6c63430008180033"; + + address target = address(uint160(uint256(keccak256(abi.encodePacked( + bytes1(0xff), + address(this), + _salt, + keccak256(abi.encodePacked(initCode)) + ))))); + + assembly { + implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt) + if iszero(extcodesize(implAddr)) { + revert(0, 0) + } + } + assert(address(implAddr) == target); + emit Deployed(implAddr, _salt); + } +} + +interface IC { + function terminate() external; +} + +contract D { + Factory public factory = new Factory(); + IC public c; + + constructor() payable {} + + function deploy_create2() public payable { + // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable + // if not performed in the same transaction. + // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun. + c = IC(factory.deploy{value: 1 ether}(hex"1234")); + } + + function terminate() public { + c.terminate(); + } + + function test_deploy_and_terminate() public { + deploy_create2(); + assert(exists()); + test_balance_after_create(); + terminate(); + test_balance_after_selfdestruct(); + } + + function test_balance_after_create() public view { + assert(address(this).balance == 0); + assert(address(c).balance == 1 ether); + } + + function test_balance_after_selfdestruct() public view { + assert(address(this).balance == 1 ether); + assert(address(c).balance == 0); + } + + function exists() public view returns (bool) { + return address(c).code.length != 0; + } +} + +// ==== +// EVMVersion: >=cancun +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 132974 +// gas irOptimized code: 293800 +// gas legacy: 151236 +// gas legacy code: 533800 +// gas legacyOptimized: 131436 +// gas legacyOptimized code: 276600 +// exists() -> false +// test_deploy_and_terminate() -> +// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 +// gas irOptimized: 96528 +// gas irOptimized code: 20800 +// gas legacy: 97788 +// gas legacy code: 20800 +// gas legacyOptimized: 96043 +// gas legacyOptimized code: 20800 +// exists() -> false +// deploy_create2() -> +// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 +// test_balance_after_create() -> +// exists() -> true +// terminate() -> +// test_balance_after_selfdestruct() -> +// exists() -> true +// deploy_create2() -> FAILURE +// gas irOptimized: 96903654 +// gas legacy: 96903658 +// gas legacyOptimized: 96903639 diff --git a/examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy_standard_input.json b/examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy_standard_input.json new file mode 100644 index 00000000..f795f56f --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_post_cancun_redeploy/selfdestruct_post_cancun_redeploy_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun.sol b/examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun.sol new file mode 100644 index 00000000..a39b6c42 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun.sol @@ -0,0 +1,89 @@ +contract C { + constructor() payable {} + + function terminate() external { + // NOTE: The contract `c` should still exists in the test below, + // since the call to the selfdestruct method was done in a tx that is + // not the same tx that the contract was created. + // However, it should send all Ether in `c` to the beneficiary. + selfdestruct(payable(msg.sender)); + assert(false); + } +} + +contract D { + C public c; + + constructor() payable {} + + function deploy_create() public payable { + c = new C{value: 1 ether}(); + } + + function deploy_create2() public payable { + c = new C{value: 1 ether, salt: hex"1234"}(); + } + + function terminate() public { + c.terminate(); + } + + function test_create_and_terminate() public { + deploy_create(); + assert(exists()); + test_balance_after_create(); + terminate(); + test_balance_after_selfdestruct(); + } + + function test_create2_and_terminate() public { + deploy_create2(); + assert(exists()); + test_balance_after_create(); + terminate(); + test_balance_after_selfdestruct(); + } + + function test_balance_after_create() public view { + assert(address(this).balance == 0); + assert(address(c).balance == 1 ether); + } + + function test_balance_after_selfdestruct() public view { + assert(address(this).balance == 1 ether); + assert(address(c).balance == 0); + } + + function exists() public view returns (bool) { + return address(c).code.length != 0; + } +} +// ==== +// EVMVersion: =shanghai +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 67028 +// gas irOptimized code: 175400 +// gas legacy: 76163 +// gas legacy code: 297400 +// gas legacyOptimized: 66516 +// gas legacyOptimized code: 168000 +// exists() -> false +// test_create_and_terminate() -> +// exists() -> false +// terminate() -> FAILURE +// deploy_create() -> +// test_balance_after_create() -> +// exists() -> true +// terminate() -> +// test_balance_after_selfdestruct() -> +// exists() -> false +// test_create2_and_terminate() -> +// exists() -> false +// deploy_create2() -> +// test_balance_after_create() -> +// exists() -> true +// terminate() -> +// test_balance_after_selfdestruct() -> +// exists() -> false +// terminate() -> FAILURE diff --git a/examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun_standard_input.json b/examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun_standard_input.json new file mode 100644 index 00000000..3d48e91d --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_pre_cancun/selfdestruct_pre_cancun_standard_input.json @@ -0,0 +1,205 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries.sol b/examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries.sol new file mode 100644 index 00000000..dbe7109c --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries.sol @@ -0,0 +1,74 @@ +contract C { + constructor() payable {} + function terminate(address _beneficiary) public { + selfdestruct(payable(_beneficiary)); + assert(false); + } +} + +contract D { + address account1 = payable(0x1111111111111111111111111111111111111111); + address account2 = payable(0x2222222222222222222222222222222222222222); + C public c; + + constructor() payable {} + + function deploy() public payable { + c = new C{value: 1 ether}(); + } + + function terminate(address _beneficiary) public { + c.terminate(_beneficiary); + } + + function test_deploy_and_terminate_twice() public { + deploy(); + terminate(account1); + terminate(account2); + } + + function exists() public view returns (bool) { + return address(c).code.length != 0; + } +} +// ==== +// EVMVersion: <=shanghai +// ---- +// constructor(), 2 ether -> +// gas irOptimized: 108104 +// gas irOptimized code: 119200 +// gas legacy: 120424 +// gas legacy code: 253600 +// gas legacyOptimized: 109015 +// gas legacyOptimized code: 130800 +// balance: 0x1111111111111111111111111111111111111111 -> 0 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 2000000000000000000 +// exists() -> false +// test_deploy_and_terminate_twice() -> +// gas irOptimized: 121395 +// gas irOptimized code: 14000 +// gas legacy: 122384 +// gas legacy code: 43200 +// gas legacyOptimized: 121596 +// gas legacyOptimized code: 22800 +// exists() -> false +// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 1000000000000000000 +// deploy() -> +// gas legacy: 58491 +// gas legacy code: 43200 +// exists() -> true +// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 0 +// terminate(address): 0x1111111111111111111111111111111111111111 -> +// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 0 +// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE +// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000 +// balance: 0x2222222222222222222222222222222222222222 -> 0 +// balance -> 0 +// exists() -> false diff --git a/examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries_standard_input.json b/examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries_standard_input.json new file mode 100644 index 00000000..3f50fd29 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_pre_cancun_multiple_beneficiaries/selfdestruct_pre_cancun_multiple_beneficiaries_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy.sol b/examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy.sol new file mode 100644 index 00000000..0d7f2334 --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy.sol @@ -0,0 +1,106 @@ +contract Factory { + event Deployed(address, bytes32); + + function deploy(bytes32 _salt) external payable returns (address implAddr) { + // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code + // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized. + //contract C { + // constructor() payable {} + // function terminate() external { + // selfdestruct(payable(msg.sender)); + // } + //} + bytes memory initCode = + hex"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0" + hex"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f" + hex"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf" + hex"ced7eff135da3556db4bd841aa64736f6c63430008180033"; + + address target = address(uint160(uint256(keccak256(abi.encodePacked( + bytes1(0xff), + address(this), + _salt, + keccak256(abi.encodePacked(initCode)) + ))))); + + assembly { + implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt) + if iszero(extcodesize(implAddr)) { + revert(0, 0) + } + } + assert(address(implAddr) == target); + emit Deployed(implAddr, _salt); + } +} + +interface IC { + function terminate() external; +} + +contract D { + Factory public factory = new Factory(); + IC public c; + + constructor() payable {} + + function deploy_create2() public payable { + c = IC(factory.deploy{value: 1 ether}(hex"1234")); + } + + function terminate() public { + c.terminate(); + } + + function test_deploy_and_terminate() public { + deploy_create2(); + assert(exists()); + test_balance_after_create(); + terminate(); + test_balance_after_selfdestruct(); + } + + function test_balance_after_create() public view { + assert(address(this).balance == 0); + assert(address(c).balance == 1 ether); + } + + function test_balance_after_selfdestruct() public view { + assert(address(this).balance == 1 ether); + assert(address(c).balance == 0); + } + + function exists() public view returns (bool) { + return address(c).code.length != 0; + } +} + +// ==== +// EVMVersion: =shanghai +// ---- +// constructor(), 1 ether -> +// gas irOptimized: 133342 +// gas irOptimized code: 298400 +// gas legacy: 151644 +// gas legacy code: 538600 +// gas legacyOptimized: 131799 +// gas legacyOptimized code: 281000 +// exists() -> false +// test_deploy_and_terminate() -> +// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 +// gas irOptimized: 96823 +// gas irOptimized code: 20800 +// gas legacy: 98095 +// gas legacy code: 20800 +// gas legacyOptimized: 96337 +// gas legacyOptimized code: 20800 +// exists() -> false +// deploy_create2() -> +// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 +// test_balance_after_create() -> +// exists() -> true +// terminate() -> +// test_balance_after_selfdestruct() -> +// exists() -> false +// deploy_create2() -> +// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy_standard_input.json b/examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy_standard_input.json new file mode 100644 index 00000000..b9dcd1cd --- /dev/null +++ b/examples/test/semanticTests/various_selfdestruct_pre_cancun_redeploy/selfdestruct_pre_cancun_redeploy_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_senders_balance/senders_balance.sol b/examples/test/semanticTests/various_senders_balance/senders_balance.sol new file mode 100644 index 00000000..fff16bef --- /dev/null +++ b/examples/test/semanticTests/various_senders_balance/senders_balance.sol @@ -0,0 +1,25 @@ +contract C { + function f() public view returns (uint256) { + return msg.sender.balance; + } +} + + +contract D { + C c = new C(); + + constructor() payable {} + + function f() public view returns (uint256) { + return c.f(); + } +} +// ---- +// constructor(), 27 wei -> +// gas irOptimized: 114057 +// gas irOptimized code: 53800 +// gas legacy: 117834 +// gas legacy code: 100600 +// gas legacyOptimized: 113676 +// gas legacyOptimized code: 53600 +// f() -> 27 diff --git a/examples/test/semanticTests/various_senders_balance/senders_balance_standard_input.json b/examples/test/semanticTests/various_senders_balance/senders_balance_standard_input.json new file mode 100644 index 00000000..de4ec62a --- /dev/null +++ b/examples/test/semanticTests/various_senders_balance/senders_balance_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance.sol b/examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance.sol new file mode 100644 index 00000000..69c4c412 --- /dev/null +++ b/examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance.sol @@ -0,0 +1,32 @@ +contract Base { + uint256 data; + + function setData(uint256 i) public { + data = i; + } + + function getViaBase() public returns (uint256 i) { + return data; + } +} + + +contract A is Base { + function setViaA(uint256 i) public { + setData(i); + } +} + + +contract B is Base { + function getViaB() public returns (uint256 i) { + return getViaBase(); + } +} + + +contract Derived is Base, B, A {} +// ---- +// getViaB() -> 0 +// setViaA(uint256): 23 -> +// getViaB() -> 23 diff --git a/examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance_standard_input.json b/examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance_standard_input.json new file mode 100644 index 00000000..5131f060 --- /dev/null +++ b/examples/test/semanticTests/various_single_copy_with_multiple_inheritance/single_copy_with_multiple_inheritance_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types.sol b/examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types.sol new file mode 100644 index 00000000..186b162c --- /dev/null +++ b/examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types.sol @@ -0,0 +1,14 @@ +// The EVM cannot provide access to dynamically-sized return values, so we have to skip them. +contract C { + function f() public returns (uint256, uint256[] memory, uint256) { + return (7, new uint256[](2), 8); + } + + function g() public returns (uint256, uint256) { + // Previous implementation "moved" b to the second place and did not skip. + (uint256 a, , uint256 b) = this.f(); + return (a, b); + } +} +// ---- +// g() -> 7, 8 diff --git a/examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types_standard_input.json b/examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types_standard_input.json new file mode 100644 index 00000000..af0efc9a --- /dev/null +++ b/examples/test/semanticTests/various_skip_dynamic_types/skip_dynamic_types_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol b/examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol new file mode 100644 index 00000000..75fdb1e8 --- /dev/null +++ b/examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol @@ -0,0 +1,23 @@ +pragma abicoder v2; + +contract C { + struct S { + bool[] b; + } + + function f() public returns (uint256, bool[][2] memory, S[2] memory, uint256) { + return ( + 5, + [new bool[](1), new bool[](2)], + [S(new bool[](2)), S(new bool[](5))], + 6 + ); + } + + function g() public returns (uint256, uint256) { + (uint256 a, , , uint256 b) = this.f(); + return (a, b); + } +} +// ---- +// g() -> 5, 6 diff --git a/examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements_standard_input.json b/examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements_standard_input.json new file mode 100644 index 00000000..996825d9 --- /dev/null +++ b/examples/test/semanticTests/various_skip_dynamic_types_for_static_arrays_with_dynamic_elements/skip_dynamic_types_for_static_arrays_with_dynamic_elements_standard_input.json @@ -0,0 +1,232 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + }, + "assignment_to_const_var_involving_expression.sol": { + "content": "contract C {\n uint256 constant x = 0x123 + 0x456;\n\n function f() public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f() -> 0x57a\n" + }, + "storage_string_as_mapping_key_without_variable.sol": { + "content": "contract Test {\n mapping(string => uint256) data;\n\n function f() public returns (uint256) {\n data[\"abc\"] = 2;\n return data[\"abc\"];\n }\n}\n// ----\n// f() -> 2\n" + }, + "skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bool[] b;\n }\n\n function f() public returns (uint256, bool[][2] memory, S[2] memory, uint256) {\n return (\n 5,\n [new bool[](1), new bool[](2)],\n [S(new bool[](2)), S(new bool[](5))],\n 6\n );\n }\n\n function g() public returns (uint256, uint256) {\n (uint256 a, , , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 5, 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs.sol b/examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs.sol new file mode 100644 index 00000000..8430da4e --- /dev/null +++ b/examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs.sol @@ -0,0 +1,24 @@ +// For accessors, the dynamic types are already removed in the external signature itself. +contract C { + struct S { + uint256 x; + string a; // this is present in the accessor + uint256[] b; // this is not present + uint256 y; + } + S public s; + + function g() public returns (uint256, uint256) { + s.x = 2; + s.a = "abc"; + s.b = [7, 8, 9]; + s.y = 6; + (uint256 x, , uint256 y) = this.s(); + return (x, y); + } +} +// ---- +// g() -> 2, 6 +// gas irOptimized: 178195 +// gas legacy: 180653 +// gas legacyOptimized: 179144 diff --git a/examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs_standard_input.json b/examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs_standard_input.json new file mode 100644 index 00000000..5cbb2842 --- /dev/null +++ b/examples/test/semanticTests/various_skip_dynamic_types_for_structs/skip_dynamic_types_for_structs_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture.sol b/examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture.sol new file mode 100644 index 00000000..f7add5fb --- /dev/null +++ b/examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture.sol @@ -0,0 +1,10 @@ +contract A { + uint256 x = 1; + uint256 y = 2; + + function a() public returns (uint256 x) { + x = A.y; + } +} +// ---- +// a() -> 2 diff --git a/examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture_standard_input.json b/examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture_standard_input.json new file mode 100644 index 00000000..d0394154 --- /dev/null +++ b/examples/test/semanticTests/various_state_variable_local_variable_mixture/state_variable_local_variable_mixture_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name.sol b/examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name.sol new file mode 100644 index 00000000..1167da57 --- /dev/null +++ b/examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name.sol @@ -0,0 +1,9 @@ +contract Scope { + uint256 stateVar = 42; + + function getStateVar() public view returns (uint256 stateVar) { + stateVar = Scope.stateVar; + } +} +// ---- +// getStateVar() -> 42 diff --git a/examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name_standard_input.json b/examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name_standard_input.json new file mode 100644 index 00000000..c5195f86 --- /dev/null +++ b/examples/test/semanticTests/various_state_variable_under_contract_name/state_variable_under_contract_name_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure.sol b/examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure.sol new file mode 100644 index 00000000..2a9834aa --- /dev/null +++ b/examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure.sol @@ -0,0 +1,53 @@ +contract C { + uint256 x; + + function f() public returns (uint256) { + x = 3; + return 1; + } +} + + +interface CView { + function f() external view returns (uint256); +} + + +interface CPure { + function f() external pure returns (uint256); +} + + +contract D { + function f() public returns (uint256) { + return (new C()).f(); + } + + function fview() public returns (uint256) { + return (CView(address(new C()))).f(); + } + + function fpure() public returns (uint256) { + return (CPure(address(new C()))).f(); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0x1 # This should work, next should throw # +// gas legacy: 76495 +// gas legacy code: 25600 +// fview() -> FAILURE +// gas irOptimized: 98425388 +// gas irOptimized code: 13200 +// gas legacy: 98413173 +// gas legacy code: 25600 +// gas legacyOptimized: 98425379 +// gas legacyOptimized code: 13200 +// fpure() -> FAILURE +// gas irOptimized: 98425388 +// gas irOptimized code: 13200 +// gas legacy: 98413173 +// gas legacy code: 25600 +// gas legacyOptimized: 98425379 +// gas legacyOptimized code: 13200 diff --git a/examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure_standard_input.json b/examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure_standard_input.json new file mode 100644 index 00000000..2b7dac9b --- /dev/null +++ b/examples/test/semanticTests/various_staticcall_for_view_and_pure/staticcall_for_view_and_pure_standard_input.json @@ -0,0 +1,211 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium.sol b/examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium.sol new file mode 100644 index 00000000..a193e875 --- /dev/null +++ b/examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium.sol @@ -0,0 +1,39 @@ +contract C { + uint256 x; + + function f() public returns (uint256) { + x = 3; + return 1; + } +} + + +interface CView { + function f() external view returns (uint256); +} + + +interface CPure { + function f() external pure returns (uint256); +} + + +contract D { + function f() public returns (uint256) { + return (new C()).f(); + } + + function fview() public returns (uint256) { + return (CView(address(new C()))).f(); + } + + function fpure() public returns (uint256) { + return (CPure(address(new C()))).f(); + } +} +// ==== +// EVMVersion: 0x1 +// fview() -> 1 +// fpure() -> 1 diff --git a/examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium_standard_input.json b/examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium_standard_input.json new file mode 100644 index 00000000..a2c99e08 --- /dev/null +++ b/examples/test/semanticTests/various_staticcall_for_view_and_pure_pre_byzantium/staticcall_for_view_and_pure_pre_byzantium_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable.sol b/examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable.sol new file mode 100644 index 00000000..df3f97eb --- /dev/null +++ b/examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable.sol @@ -0,0 +1,10 @@ +contract Test { + mapping(string => uint256) data; + + function f() public returns (uint256) { + data["abc"] = 2; + return data["abc"]; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable_standard_input.json b/examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable_standard_input.json new file mode 100644 index 00000000..ac53fb4e --- /dev/null +++ b/examples/test/semanticTests/various_storage_string_as_mapping_key_without_variable/storage_string_as_mapping_key_without_variable_standard_input.json @@ -0,0 +1,229 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + }, + "assignment_to_const_var_involving_expression.sol": { + "content": "contract C {\n uint256 constant x = 0x123 + 0x456;\n\n function f() public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f() -> 0x57a\n" + }, + "storage_string_as_mapping_key_without_variable.sol": { + "content": "contract Test {\n mapping(string => uint256) data;\n\n function f() public returns (uint256) {\n data[\"abc\"] = 2;\n return data[\"abc\"];\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_store_bytes/store_bytes.sol b/examples/test/semanticTests/various_store_bytes/store_bytes.sol new file mode 100644 index 00000000..4b92a251 --- /dev/null +++ b/examples/test/semanticTests/various_store_bytes/store_bytes.sol @@ -0,0 +1,13 @@ +// this test just checks that the copy loop does not mess up the stack +contract C { + function save() public returns (uint256 r) { + r = 23; + savedData = msg.data; + r = 24; + } + + bytes savedData; +} +// ---- +// save() -> 24 # empty copy loop # +// save(): "abcdefg" -> 24 diff --git a/examples/test/semanticTests/various_store_bytes/store_bytes_standard_input.json b/examples/test/semanticTests/various_store_bytes/store_bytes_standard_input.json new file mode 100644 index 00000000..edfc66eb --- /dev/null +++ b/examples/test/semanticTests/various_store_bytes/store_bytes_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_string_tuples/string_tuples.sol b/examples/test/semanticTests/various_string_tuples/string_tuples.sol new file mode 100644 index 00000000..57028ae3 --- /dev/null +++ b/examples/test/semanticTests/various_string_tuples/string_tuples.sol @@ -0,0 +1,16 @@ +contract C { + function f() public returns (string memory, uint256) { + return ("abc", 8); + } + + function g() public returns (string memory, string memory) { + return (h(), "def"); + } + + function h() public returns (string memory) { + return ("abc"); + } +} +// ---- +// f() -> 0x40, 0x8, 0x3, "abc" +// g() -> 0x40, 0x80, 0x3, "abc", 0x3, "def" diff --git a/examples/test/semanticTests/various_string_tuples/string_tuples_standard_input.json b/examples/test/semanticTests/various_string_tuples/string_tuples_standard_input.json new file mode 100644 index 00000000..070a7732 --- /dev/null +++ b/examples/test/semanticTests/various_string_tuples/string_tuples_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_super/super.sol b/examples/test/semanticTests/various_super/super.sol new file mode 100644 index 00000000..cd1b4a71 --- /dev/null +++ b/examples/test/semanticTests/various_super/super.sol @@ -0,0 +1,28 @@ +contract A { + function f() public virtual returns (uint256 r) { + return 1; + } +} + + +contract B is A { + function f() public virtual override returns (uint256 r) { + return super.f() | 2; + } +} + + +contract C is A { + function f() public virtual override returns (uint256 r) { + return super.f() | 4; + } +} + + +contract D is B, C { + function f() public override(B, C) returns (uint256 r) { + return super.f() | 8; + } +} +// ---- +// f() -> 15 diff --git a/examples/test/semanticTests/various_super/super_standard_input.json b/examples/test/semanticTests/various_super/super_standard_input.json new file mode 100644 index 00000000..98515ede --- /dev/null +++ b/examples/test/semanticTests/various_super/super_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_super_alone/super_alone.sol b/examples/test/semanticTests/various_super_alone/super_alone.sol new file mode 100644 index 00000000..223e3176 --- /dev/null +++ b/examples/test/semanticTests/various_super_alone/super_alone.sol @@ -0,0 +1,7 @@ +contract A { + function f() public { + super; + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/various_super_alone/super_alone_standard_input.json b/examples/test/semanticTests/various_super_alone/super_alone_standard_input.json new file mode 100644 index 00000000..fd947be6 --- /dev/null +++ b/examples/test/semanticTests/various_super_alone/super_alone_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_super_parentheses/super_parentheses.sol b/examples/test/semanticTests/various_super_parentheses/super_parentheses.sol new file mode 100644 index 00000000..fd794476 --- /dev/null +++ b/examples/test/semanticTests/various_super_parentheses/super_parentheses.sol @@ -0,0 +1,28 @@ +contract A { + function f() public virtual returns (uint256 r) { + return 1; + } +} + + +contract B is A { + function f() public virtual override returns (uint256 r) { + return ((super).f)() | 2; + } +} + + +contract C is A { + function f() public virtual override returns (uint256 r) { + return ((super).f)() | 4; + } +} + + +contract D is B, C { + function f() public override(B, C) returns (uint256 r) { + return ((super).f)() | 8; + } +} +// ---- +// f() -> 15 diff --git a/examples/test/semanticTests/various_super_parentheses/super_parentheses_standard_input.json b/examples/test/semanticTests/various_super_parentheses/super_parentheses_standard_input.json new file mode 100644 index 00000000..6588fc67 --- /dev/null +++ b/examples/test/semanticTests/various_super_parentheses/super_parentheses_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite.sol b/examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite.sol new file mode 100644 index 00000000..3422c812 --- /dev/null +++ b/examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite.sol @@ -0,0 +1,36 @@ +// This tests a swap in storage which does not work as one +// might expect because we do not have temporary storage. +// (x, y) = (y, x) is the same as +// y = x; +// x = y; +contract c { + struct S { + uint256 a; + uint256 b; + } + S public x; + S public y; + + function set() public { + x.a = 1; + x.b = 2; + y.a = 3; + y.b = 4; + } + + function swap() public { + (x, y) = (y, x); + } +} +// ---- +// x() -> 0, 0 +// y() -> 0, 0 +// set() -> +// gas irOptimized: 109684 +// gas legacy: 109727 +// gas legacyOptimized: 109680 +// x() -> 1, 2 +// y() -> 3, 4 +// swap() -> +// x() -> 1, 2 +// y() -> 1, 2 diff --git a/examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite_standard_input.json b/examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite_standard_input.json new file mode 100644 index 00000000..49df6b3e --- /dev/null +++ b/examples/test/semanticTests/various_swap_in_storage_overwrite/swap_in_storage_overwrite_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex.sol b/examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex.sol new file mode 100644 index 00000000..b9503e44 --- /dev/null +++ b/examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex.sol @@ -0,0 +1,10 @@ +contract test { + function f(bool cond) public pure returns (uint256) { + uint32 x = 0x1234_ab; + uint256 y = 0x1234_abcd_1234; + return cond ? x : y; + } +} +// ---- +// f(bool): true -> 0x1234ab +// f(bool): false -> 0x1234abcd1234 diff --git a/examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex_standard_input.json b/examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex_standard_input.json new file mode 100644 index 00000000..4d1eac5c --- /dev/null +++ b/examples/test/semanticTests/various_test_underscore_in_hex/test_underscore_in_hex_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock.sol b/examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock.sol new file mode 100644 index 00000000..cc3a9d4a --- /dev/null +++ b/examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock.sol @@ -0,0 +1,23 @@ +contract C { + bool transient locked; + modifier nonReentrant { + require(!locked, "Reentrancy attempt"); + locked = true; + _; + locked = false; + } + + function test(address newAddress, bool reentrancy) nonReentrant public { + if (reentrancy) + reentrantCall(newAddress); + } + + function reentrantCall(address a) public { + this.test(a, false); + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// test(address,bool): 0x1234abcd, true -> FAILURE, hex"08c379a0", 0x20, 0x12, "Reentrancy attempt" +// test(address,bool): 0x1234abcd, false -> diff --git a/examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock_standard_input.json b/examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock_standard_input.json new file mode 100644 index 00000000..87ceb4ca --- /dev/null +++ b/examples/test/semanticTests/various_transient_storage_reentrancy_lock/transient_storage_reentrancy_lock_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_tuples/tuples.sol b/examples/test/semanticTests/various_tuples/tuples.sol new file mode 100644 index 00000000..45800759 --- /dev/null +++ b/examples/test/semanticTests/various_tuples/tuples.sol @@ -0,0 +1,29 @@ +contract C { + uint256[] data; + uint256[] m_c; + + function g() internal returns (uint256 a, uint256 b, uint256[] storage c) { + return (1, 2, data); + } + + function h() external returns (uint256 a, uint256 b) { + return (5, 6); + } + + function f() public returns (uint256) { + data.push(3); + uint256 a; + uint256 b; + (a, b) = this.h(); + if (a != 5 || b != 6) return 1; + uint256[] storage c = m_c; + (a, b, c) = g(); + if (a != 1 || b != 2 || c[0] != 3) return 2; + (a, b) = (b, a); + if (a != 2 || b != 1) return 3; + (a, , b, , ) = (8, 9, 10, 11, 12); + if (a != 8 || b != 10) return 4; + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/various_tuples/tuples_standard_input.json b/examples/test/semanticTests/various_tuples/tuples_standard_input.json new file mode 100644 index 00000000..cad7ba52 --- /dev/null +++ b/examples/test/semanticTests/various_tuples/tuples_standard_input.json @@ -0,0 +1,238 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + }, + "assignment_to_const_var_involving_expression.sol": { + "content": "contract C {\n uint256 constant x = 0x123 + 0x456;\n\n function f() public returns (uint256) {\n return x + 1;\n }\n}\n// ----\n// f() -> 0x57a\n" + }, + "storage_string_as_mapping_key_without_variable.sol": { + "content": "contract Test {\n mapping(string => uint256) data;\n\n function f() public returns (uint256) {\n data[\"abc\"] = 2;\n return data[\"abc\"];\n }\n}\n// ----\n// f() -> 2\n" + }, + "skip_dynamic_types_for_static_arrays_with_dynamic_elements.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n bool[] b;\n }\n\n function f() public returns (uint256, bool[][2] memory, S[2] memory, uint256) {\n return (\n 5,\n [new bool[](1), new bool[](2)],\n [S(new bool[](2)), S(new bool[](5))],\n 6\n );\n }\n\n function g() public returns (uint256, uint256) {\n (uint256 a, , , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 5, 6\n" + }, + "empty_name_return_parameter.sol": { + "content": "contract test {\n function f(uint256 k) public returns (uint256) {\n return k;\n }\n}\n// ----\n// f(uint256): 9 -> 9\n" + }, + "tuples.sol": { + "content": "contract C {\n uint256[] data;\n uint256[] m_c;\n\n function g() internal returns (uint256 a, uint256 b, uint256[] storage c) {\n return (1, 2, data);\n }\n\n function h() external returns (uint256 a, uint256 b) {\n return (5, 6);\n }\n\n function f() public returns (uint256) {\n data.push(3);\n uint256 a;\n uint256 b;\n (a, b) = this.h();\n if (a != 5 || b != 6) return 1;\n uint256[] storage c = m_c;\n (a, b, c) = g();\n if (a != 1 || b != 2 || c[0] != 3) return 2;\n (a, b) = (b, a);\n if (a != 2 || b != 1) return 3;\n (a, , b, , ) = (8, 9, 10, 11, 12);\n if (a != 8 || b != 10) return 4;\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration.sol b/examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration.sol new file mode 100644 index 00000000..c9f12fda --- /dev/null +++ b/examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration.sol @@ -0,0 +1,25 @@ +contract C { + struct S { + uint256 x; + } + S s; + + function g() internal returns (uint256, S storage, uint256) { + s.x = 7; + return (1, s, 2); + } + + function f() public returns (bool) { + (uint256 x1, S storage y1, uint256 z1) = g(); + if (x1 != 1 || y1.x != 7 || z1 != 2) return false; + (, S storage y2, ) = g(); + if (y2.x != 7) return false; + (uint256 x2, , ) = g(); + if (x2 != 1) return false; + (, , uint256 z2) = g(); + if (z2 != 2) return false; + return true; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration_standard_input.json b/examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration_standard_input.json new file mode 100644 index 00000000..60f1ed80 --- /dev/null +++ b/examples/test/semanticTests/various_typed_multi_variable_declaration/typed_multi_variable_declaration_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_value_complex/value_complex.sol b/examples/test/semanticTests/various_value_complex/value_complex.sol new file mode 100644 index 00000000..4639d34c --- /dev/null +++ b/examples/test/semanticTests/various_value_complex/value_complex.sol @@ -0,0 +1,28 @@ +contract helper { + function getBalance() public payable returns (uint256 myBalance) { + return address(this).balance; + } +} + + +contract test { + helper h; + + constructor() payable { + h = new helper(); + } + + function sendAmount(uint256 amount) public payable returns (uint256 bal) { + uint256 someStackElement = 20; + return h.getBalance{value: amount + 3, gas: 1000}(); + } +} +// ---- +// constructor(), 20 wei -> +// gas irOptimized: 114463 +// gas irOptimized code: 58800 +// gas legacy: 120091 +// gas legacy code: 132400 +// gas legacyOptimized: 114536 +// gas legacyOptimized code: 65800 +// sendAmount(uint256): 5 -> 8 diff --git a/examples/test/semanticTests/various_value_complex/value_complex_standard_input.json b/examples/test/semanticTests/various_value_complex/value_complex_standard_input.json new file mode 100644 index 00000000..0635fcfb --- /dev/null +++ b/examples/test/semanticTests/various_value_complex/value_complex_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_value_insane/value_insane.sol b/examples/test/semanticTests/various_value_insane/value_insane.sol new file mode 100644 index 00000000..bc6a803d --- /dev/null +++ b/examples/test/semanticTests/various_value_insane/value_insane.sol @@ -0,0 +1,27 @@ +contract helper { + function getBalance() public payable returns (uint256 myBalance) { + return address(this).balance; + } +} + + +contract test { + helper h; + + constructor() payable { + h = new helper(); + } + + function sendAmount(uint256 amount) public returns (uint256 bal) { + return h.getBalance{value: amount + 3, gas: 1000}(); + } +} +// ---- +// constructor(), 20 wei -> +// gas irOptimized: 114527 +// gas irOptimized code: 59600 +// gas legacy: 120199 +// gas legacy code: 133600 +// gas legacyOptimized: 114568 +// gas legacyOptimized code: 66200 +// sendAmount(uint256): 5 -> 8 diff --git a/examples/test/semanticTests/various_value_insane/value_insane_standard_input.json b/examples/test/semanticTests/various_value_insane/value_insane_standard_input.json new file mode 100644 index 00000000..ed8fc437 --- /dev/null +++ b/examples/test/semanticTests/various_value_insane/value_insane_standard_input.json @@ -0,0 +1,214 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/various_write_storage_external/write_storage_external.sol b/examples/test/semanticTests/various_write_storage_external/write_storage_external.sol new file mode 100644 index 00000000..a8959b24 --- /dev/null +++ b/examples/test/semanticTests/various_write_storage_external/write_storage_external.sol @@ -0,0 +1,39 @@ +contract C { + uint256 public x; + + function f(uint256 y) public payable { + x = y; + } + + function g(uint256 y) external { + x = y; + } + + function h() public { + this.g(12); + } +} + + +contract D { + C c = new C(); + + function f() public payable returns (uint256) { + c.g(3); + return c.x(); + } + + function g() public returns (uint256) { + c.g(8); + return c.x(); + } + + function h() public returns (uint256) { + c.h(); + return c.x(); + } +} +// ---- +// f() -> 3 +// g() -> 8 +// h() -> 12 diff --git a/examples/test/semanticTests/various_write_storage_external/write_storage_external_standard_input.json b/examples/test/semanticTests/various_write_storage_external/write_storage_external_standard_input.json new file mode 100644 index 00000000..2af89dc6 --- /dev/null +++ b/examples/test/semanticTests/various_write_storage_external/write_storage_external_standard_input.json @@ -0,0 +1,223 @@ +{ + "language": "Solidity", + "sources": { + "senders_balance.sol": { + "content": "contract C {\n function f() public view returns (uint256) {\n return msg.sender.balance;\n }\n}\n\n\ncontract D {\n C c = new C();\n\n constructor() payable {}\n\n function f() public view returns (uint256) {\n return c.f();\n }\n}\n// ----\n// constructor(), 27 wei ->\n// gas irOptimized: 114057\n// gas irOptimized code: 53800\n// gas legacy: 117834\n// gas legacy code: 100600\n// gas legacyOptimized: 113676\n// gas legacyOptimized code: 53600\n// f() -> 27\n" + }, + "codebalance_assembly.sol": { + "content": "contract C {\n constructor() payable {}\n\n function f() public returns (uint256 ret) {\n assembly {\n ret := balance(0)\n }\n }\n function g() public returns (uint256 ret) {\n assembly {\n ret := balance(1)\n }\n }\n function h() public returns (uint256 ret) {\n assembly {\n ret := balance(address())\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// constructor(), 23 wei ->\n// gas legacy: 100517\n// f() -> 0\n// g() -> 1\n// h() -> 23\n" + }, + "multi_variable_declaration.sol": { + "content": "contract C {\n function g() public returns (uint256 a, uint256 b, uint256 c) {\n a = 1;\n b = 2;\n c = 3;\n }\n\n function h() public returns (uint256 a, uint256 b, uint256 c, uint256 d) {\n a = 1;\n b = 2;\n c = 3;\n d = 4;\n }\n\n function f1() public returns (bool) {\n (uint256 x, uint256 y, uint256 z) = g();\n if (x != 1 || y != 2 || z != 3) return false;\n (, uint256 a, ) = g();\n if (a != 2) return false;\n (uint256 b, , ) = g();\n if (b != 1) return false;\n (, , uint256 c) = g();\n if (c != 3) return false;\n return true;\n }\n\n function f2() public returns (bool) {\n (uint256 a1, , uint256 a3, ) = h();\n if (a1 != 1 || a3 != 3) return false;\n (uint256 b1, uint256 b2, , ) = h();\n if (b1 != 1 || b2 != 2) return false;\n (, uint256 c2, uint256 c3, ) = h();\n if (c2 != 2 || c3 != 3) return false;\n (, , uint256 d3, uint256 d4) = h();\n if (d3 != 3 || d4 != 4) return false;\n (uint256 e1, , uint256 e3, uint256 e4) = h();\n if (e1 != 1 || e3 != 3 || e4 != 4) return false;\n return true;\n }\n\n function f() public returns (bool) {\n return f1() && f2();\n }\n}\n// ----\n// f() -> true\n" + }, + "crazy_elementary_typenames_on_stack.sol": { + "content": "contract C {\n function f() public returns (uint256 r) {\n uint256;\n uint256;\n uint256;\n uint256;\n int256 x = -7;\n return uint256(x);\n }\n}\n// ----\n// f() -> -7\n" + }, + "code_access_create.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\n\ncontract C {\n function test() public returns (uint256) {\n bytes memory c = type(D).creationCode;\n D d;\n assembly {\n d := create(0, add(c, 0x20), mload(c))\n }\n return d.f();\n }\n}\n// ----\n// test() -> 7\n// gas legacy: 76647\n// gas legacy code: 24200\n" + }, + "string_tuples.sol": { + "content": "contract C {\n function f() public returns (string memory, uint256) {\n return (\"abc\", 8);\n }\n\n function g() public returns (string memory, string memory) {\n return (h(), \"def\");\n }\n\n function h() public returns (string memory) {\n return (\"abc\");\n }\n}\n// ----\n// f() -> 0x40, 0x8, 0x3, \"abc\"\n// g() -> 0x40, 0x80, 0x3, \"abc\", 0x3, \"def\"\n" + }, + "erc20.sol": { + "content": "pragma solidity >=0.4.0 <0.9.0;\n\ncontract ERC20 {\n event Transfer(address indexed from, address indexed to, uint256 value);\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n mapping (address => uint256) private _balances;\n mapping (address => mapping (address => uint256)) private _allowances;\n uint256 private _totalSupply;\n\n constructor() {\n _mint(msg.sender, 20);\n }\n\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowances[owner][spender];\n }\n\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n function approve(address spender, uint256 value) public returns (bool) {\n _approve(msg.sender, spender, value);\n return true;\n }\n\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _transfer(from, to, value);\n // The subtraction here will revert on overflow.\n _approve(from, msg.sender, _allowances[from][msg.sender] - value);\n return true;\n }\n\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n // The addition here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] + addedValue);\n return true;\n }\n\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n // The subtraction here will revert on overflow.\n _approve(msg.sender, spender, _allowances[msg.sender][spender] - subtractedValue);\n return true;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n // The subtraction and addition here will revert on overflow.\n _balances[from] = _balances[from] - value;\n _balances[to] = _balances[to] + value;\n emit Transfer(from, to, value);\n }\n\n function _mint(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n // The additions here will revert on overflow.\n _totalSupply = _totalSupply + value;\n _balances[account] = _balances[account] + value;\n emit Transfer(address(0), account, value);\n }\n\n function _burn(address account, uint256 value) internal {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n // The subtractions here will revert on overflow.\n _totalSupply = _totalSupply - value;\n _balances[account] = _balances[account] - value;\n emit Transfer(account, address(0), value);\n }\n\n function _approve(address owner, address spender, uint256 value) internal {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = value;\n emit Approval(owner, spender, value);\n }\n\n function _burnFrom(address account, uint256 value) internal {\n _burn(account, value);\n _approve(account, msg.sender, _allowances[account][msg.sender] - value);\n }\n}\n// ----\n// constructor()\n// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14\n// gas irOptimized: 121632\n// gas irOptimized code: 236800\n// gas legacy: 159957\n// gas legacy code: 647600\n// gas legacyOptimized: 126934\n// gas legacyOptimized code: 282000\n// totalSupply() -> 20\n// gas irOptimized: 23415\n// gas legacy: 23524\n// gas legacyOptimized: 23368\n// transfer(address,uint256): 2, 5 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x05\n// gas irOptimized: 48471\n// gas legacy: 49317\n// gas legacyOptimized: 48491\n// decreaseAllowance(address,uint256): 2, 0 -> true\n// ~ emit Approval(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x00\n// gas irOptimized: 26275\n// gas legacy: 27012\n// gas legacyOptimized: 26275\n// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24042\n// gas legacy: 24467\n// gas legacyOptimized: 24056\n// transfer(address,uint256): 2, 14 -> true\n// ~ emit Transfer(address,address,uint256): #0x1212121212121212121212121212120000000012, #0x02, 0x0e\n// gas irOptimized: 28571\n// gas legacy: 29417\n// gas legacyOptimized: 28591\n// transfer(address,uint256): 2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// gas irOptimized: 24071\n// gas legacy: 24453\n// gas legacyOptimized: 24053\n" + }, + "byte_optimization_bug.sol": { + "content": "contract C {\n function f(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(x, 31)\n }\n }\n\n function g(uint256 x) public returns (uint256 a) {\n assembly {\n a := byte(31, x)\n }\n }\n}\n// ----\n// f(uint256): 2 -> 0\n// g(uint256): 2 -> 2\n" + }, + "nested_calldata_struct.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n return (s.a, s.b, s.s.a, s.s.b, s.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "swap_in_storage_overwrite.sol": { + "content": "// This tests a swap in storage which does not work as one\n// might expect because we do not have temporary storage.\n// (x, y) = (y, x) is the same as\n// y = x;\n// x = y;\ncontract c {\n struct S {\n uint256 a;\n uint256 b;\n }\n S public x;\n S public y;\n\n function set() public {\n x.a = 1;\n x.b = 2;\n y.a = 3;\n y.b = 4;\n }\n\n function swap() public {\n (x, y) = (y, x);\n }\n}\n// ----\n// x() -> 0, 0\n// y() -> 0, 0\n// set() ->\n// gas irOptimized: 109684\n// gas legacy: 109727\n// gas legacyOptimized: 109680\n// x() -> 1, 2\n// y() -> 3, 4\n// swap() ->\n// x() -> 1, 2\n// y() -> 1, 2\n" + }, + "store_bytes.sol": { + "content": "// this test just checks that the copy loop does not mess up the stack\ncontract C {\n function save() public returns (uint256 r) {\n r = 23;\n savedData = msg.data;\n r = 24;\n }\n\n bytes savedData;\n}\n// ----\n// save() -> 24 # empty copy loop #\n// save(): \"abcdefg\" -> 24\n" + }, + "state_variable_local_variable_mixture.sol": { + "content": "contract A {\n uint256 x = 1;\n uint256 y = 2;\n\n function a() public returns (uint256 x) {\n x = A.y;\n }\n}\n// ----\n// a() -> 2\n" + }, + "inline_member_init.sol": { + "content": "contract test {\n constructor() {\n m_b = 6;\n m_c = 8;\n }\n\n uint256 m_a = 5;\n uint256 m_b;\n uint256 m_c = 7;\n\n function get() public returns (uint256 a, uint256 b, uint256 c) {\n a = m_a;\n b = m_b;\n c = m_c;\n }\n}\n// ----\n// get() -> 5, 6, 8\n" + }, + "selfdestruct_pre_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: <=shanghai\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120424\n// gas legacy code: 253600\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122384\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x2222222222222222222222222222222222222222 -> FAILURE\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> false\n" + }, + "destructuring_assignment.sol": { + "content": "contract C {\n uint256 x = 7;\n bytes data;\n uint256[] y;\n uint256[] arrayData;\n\n function returnsArray() public returns (uint256[] memory) {\n arrayData = new uint256[](9);\n arrayData[2] = 5;\n arrayData[7] = 4;\n return arrayData;\n }\n\n function f(bytes memory s) public returns (uint256) {\n uint256 loc;\n uint256[] memory memArray;\n (loc, x, y, data, arrayData[3]) = (8, 4, returnsArray(), s, 2);\n if (loc != 8) return 1;\n if (x != 4) return 2;\n if (y.length != 9) return 3;\n if (y[2] != 5) return 4;\n if (y[7] != 4) return 5;\n if (data.length != s.length) return 6;\n if (data[3] != s[3]) return 7;\n if (arrayData[3] != 2) return 8;\n (memArray, loc) = (arrayData, 3);\n if (loc != 3) return 9;\n if (memArray.length != arrayData.length) return 10;\n bytes memory memBytes;\n (x, memBytes, y[2], , ) = (456, s, 789, 101112, 131415);\n if (x != 456 || memBytes.length != s.length || y[2] != 789) return 11;\n }\n}\n// ----\n// f(bytes): 0x20, 0x5, \"abcde\" -> 0\n// gas irOptimized: 242027\n// gas legacy: 243281\n// gas legacyOptimized: 242392\n" + }, + "external_types_in_calls.sol": { + "content": "contract C1 {\n C1 public bla;\n\n constructor(C1 x) {\n bla = x;\n }\n}\n\n\ncontract C {\n function test() public returns (C1 x, C1 y) {\n C1 c = new C1(C1(address(9)));\n x = c.bla();\n y = this.t1(C1(address(7)));\n }\n\n function t1(C1 a) public returns (C1) {\n return a;\n }\n\n function t2() public returns (C1) {\n return C1(address(9));\n }\n}\n// ----\n// test() -> 9, 7\n// gas legacy: 80314\n// gas legacy code: 47400\n// t2() -> 9\n" + }, + "codehash_assembly.sol": { + "content": "contract C {\n function f() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(0)\n }\n }\n function g() public returns (bytes32 ret) {\n assembly {\n ret := extcodehash(1)\n }\n }\n function h() public returns (bool ret) {\n assembly {\n ret := iszero(iszero(extcodehash(address())))\n }\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "staticcall_for_view_and_pure_pre_byzantium.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: 0x1\n// fview() -> 1\n// fpure() -> 1\n" + }, + "skip_dynamic_types.sol": { + "content": "// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.\ncontract C {\n function f() public returns (uint256, uint256[] memory, uint256) {\n return (7, new uint256[](2), 8);\n }\n\n function g() public returns (uint256, uint256) {\n // Previous implementation \"moved\" b to the second place and did not skip.\n (uint256 a, , uint256 b) = this.f();\n return (a, b);\n }\n}\n// ----\n// g() -> 7, 8\n" + }, + "gasleft_shadow_resolution.sol": { + "content": "contract C {\n function gasleft() public returns (uint256) {\n return 0;\n }\n\n function f() public returns (uint256) {\n return gasleft();\n }\n}\n// ----\n// f() -> 0\n" + }, + "codehash.sol": { + "content": "contract C {\n function f() public returns (bytes32) {\n // non-existent in tests\n return address(0).codehash;\n }\n function g() public returns (bytes32) {\n // precompile\n return address(0x1).codehash;\n }\n function h() public returns (bool) {\n return address(this).codehash != 0;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// f() -> 0x0\n// g() -> 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470\n// h() -> true\n" + }, + "transient_storage_reentrancy_lock.sol": { + "content": "contract C {\n bool transient locked;\n modifier nonReentrant {\n require(!locked, \"Reentrancy attempt\");\n locked = true;\n _;\n locked = false;\n }\n\n function test(address newAddress, bool reentrancy) nonReentrant public {\n if (reentrancy)\n reentrantCall(newAddress);\n }\n\n function reentrantCall(address a) public {\n this.test(a, false);\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// test(address,bool): 0x1234abcd, true -> FAILURE, hex\"08c379a0\", 0x20, 0x12, \"Reentrancy attempt\"\n// test(address,bool): 0x1234abcd, false ->\n" + }, + "contract_binary_dependencies.sol": { + "content": "contract A {\n function f() public {\n new B();\n }\n}\n\n\ncontract B {\n function f() public {}\n}\n\n\ncontract C {\n function f() public {\n new B();\n }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 100415\n" + }, + "flipping_sign_tests.sol": { + "content": "contract test {\n function f() public returns (bool) {\n int256 x = -2**255;\n unchecked { assert(-x == x); }\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "different_call_type_transient.sol": { + "content": "contract B {\n uint256 transient public value;\n\n function setValue(uint256 v) public {\n value += v;\n }\n}\n\ncontract A {\n uint256 transient public value;\n\n function delegateSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.delegatecall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function callSetValue(address otherContract, uint256 v) public {\n (bool success, ) = otherContract.call(abi.encodeWithSignature(\"setValue(uint256)\", v));\n require(success);\n }\n function staticSetValue(address otherContract, uint256 v) view public returns (bool) {\n (bool success, ) = otherContract.staticcall(abi.encodeWithSignature(\"setValue(uint256)\", v));\n return success;\n }\n}\n\ncontract Test {\n A a = new A();\n B b = new B();\n\n function testDelegate() public returns (uint256, uint256) {\n a.delegateSetValue(address(b), 7);\n return (a.value(), b.value());\n }\n function testCall() public returns (uint256, uint256) {\n a.callSetValue(address(b), 8);\n return (a.value(), b.value());\n }\n function testStatic() view public returns (bool) {\n return a.staticSetValue(address(b), 0);\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// testDelegate() -> 7, 0\n// testCall() -> 0, 8\n// testStatic() -> false\n// gas irOptimized: 96900694\n// gas legacy: 96901136\n// gas legacyOptimized: 96900725\n" + }, + "state_variable_under_contract_name.sol": { + "content": "contract Scope {\n uint256 stateVar = 42;\n\n function getStateVar() public view returns (uint256 stateVar) {\n stateVar = Scope.stateVar;\n }\n}\n// ----\n// getStateVar() -> 42\n" + }, + "address_code.sol": { + "content": "contract C {\n bytes public initCode;\n\n constructor() {\n // This should catch problems, but lets also test the case the optimiser is buggy.\n assert(address(this).code.length == 0);\n initCode = address(this).code;\n }\n\n // To avoid dependency on exact length.\n function f() public view returns (bool) { return address(this).code.length > 380; }\n function g() public view returns (uint) { return address(0).code.length; }\n function h() public view returns (uint) { return address(1).code.length; }\n}\n// ----\n// constructor() ->\n// gas irOptimized: 70760\n// gas irOptimized code: 94600\n// gas legacy: 82428\n// gas legacy code: 153800\n// gas legacyOptimized: 69400\n// gas legacyOptimized code: 79200\n// initCode() -> 0x20, 0\n// f() -> true\n// g() -> 0\n// h() -> 0\n" + }, + "super.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return super.f() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return super.f() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "decayed_tuple.sol": { + "content": "contract C {\n function f() public returns (uint256) {\n uint256 x = 1;\n (x) = 2;\n return x;\n }\n}\n// ----\n// f() -> 2\n" + }, + "selfdestruct_pre_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 133342\n// gas irOptimized code: 298400\n// gas legacy: 151644\n// gas legacy code: 538600\n// gas legacyOptimized: 131799\n// gas legacyOptimized code: 281000\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96823\n// gas irOptimized code: 20800\n// gas legacy: 98095\n// gas legacy code: 20800\n// gas legacyOptimized: 96337\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n" + }, + "test_underscore_in_hex.sol": { + "content": "contract test {\n function f(bool cond) public pure returns (uint256) {\n uint32 x = 0x1234_ab;\n uint256 y = 0x1234_abcd_1234;\n return cond ? x : y;\n }\n}\n// ----\n// f(bool): true -> 0x1234ab\n// f(bool): false -> 0x1234abcd1234\n" + }, + "skip_dynamic_types_for_structs.sol": { + "content": "// For accessors, the dynamic types are already removed in the external signature itself.\ncontract C {\n struct S {\n uint256 x;\n string a; // this is present in the accessor\n uint256[] b; // this is not present\n uint256 y;\n }\n S public s;\n\n function g() public returns (uint256, uint256) {\n s.x = 2;\n s.a = \"abc\";\n s.b = [7, 8, 9];\n s.y = 6;\n (uint256 x, , uint256 y) = this.s();\n return (x, y);\n }\n}\n// ----\n// g() -> 2, 6\n// gas irOptimized: 178195\n// gas legacy: 180653\n// gas legacyOptimized: 179144\n" + }, + "code_length.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\ncontract C {\n uint len1;\n uint len2;\n constructor() {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n len1 = address(0).code.length;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n len2 = address(this).code.length;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n assert(mem_ptr_before == mem_ptr_after);\n\n }\n\n function f() public view returns (bool r1, bool r2) {\n uint mem_ptr_before;\n uint mem_ptr_after;\n\n assembly {\n mem_ptr_before := mload(64)\n }\n\n r1 = address(this).code.length > 50;\n\n assembly {\n mem_ptr_after := mload(64)\n }\n\n // To check that no memory was allocated and written.\n assert(mem_ptr_before == mem_ptr_after);\n\n address a = address(0);\n r2 = a.code.length == 0;\n\n // To check that no memory was allocated and written.\n assembly {\n mem_ptr_after := mload(64)\n }\n\n }\n}\n// ----\n// constructor()\n// gas legacy: 66989\n// gas legacy code: 57800\n// f(): true, true -> true, true\n" + }, + "memory_overwrite.sol": { + "content": "contract C {\n function f() public returns (bytes memory x) {\n x = \"12345\";\n x[3] = 0x61;\n x[0] = 0x62;\n }\n}\n// ----\n// f() -> 0x20, 5, \"b23a5\"\n" + }, + "cross_contract_types.sol": { + "content": "contract Lib {\n struct S {\n uint256 a;\n uint256 b;\n }\n}\n\n\ncontract Test {\n function f() public returns (uint256 r) {\n Lib.S memory x = Lib.S({a: 2, b: 3});\n r = x.b;\n }\n}\n// ----\n// f() -> 3\n" + }, + "multi_modifiers.sol": { + "content": "// This triggered a bug in some version because the variable in the modifier was not\n// unregistered correctly.\ncontract C {\n uint256 public x;\n modifier m1 {\n address a1 = msg.sender;\n x++;\n _;\n }\n\n function f1() public m1() {\n x += 7;\n }\n\n function f2() public m1() {\n x += 3;\n }\n}\n// ----\n// f1() ->\n// x() -> 0x08\n// f2() ->\n// x() -> 0x0c\n" + }, + "create_calldata.sol": { + "content": "contract C {\n\tbytes public s;\n\tconstructor(uint256 x) {\n\t\t// Due to a bug in EVMHost, msg.data used to contain initcode and constructor arguments.\n\t\ts = msg.data;\n\t\tassert(msg.data.length == 0);\n\t}\n}\n// ----\n// constructor(): 42 ->\n// gas irOptimized: 68239\n// gas irOptimized code: 69000\n// gas legacy: 78076\n// gas legacy code: 90200\n// gas legacyOptimized: 68321\n// gas legacyOptimized code: 64600\n// s() -> 0x20, 0\n" + }, + "code_length_contract_member.sol": { + "content": "// Test to see if type.code.length does extcodesize(type) only when type is an address.\nstruct S {\n bytes32 code;\n bytes32 another;\n}\n\ncontract C {\n S s;\n\n function f() public returns (uint, uint, bool) {\n return (s.code.length, s.another.length, address(this).code.length > 50);\n }\n}\n// ----\n// f() -> 0x20, 0x20, true\n" + }, + "single_copy_with_multiple_inheritance.sol": { + "content": "contract Base {\n uint256 data;\n\n function setData(uint256 i) public {\n data = i;\n }\n\n function getViaBase() public returns (uint256 i) {\n return data;\n }\n}\n\n\ncontract A is Base {\n function setViaA(uint256 i) public {\n setData(i);\n }\n}\n\n\ncontract B is Base {\n function getViaB() public returns (uint256 i) {\n return getViaBase();\n }\n}\n\n\ncontract Derived is Base, B, A {}\n// ----\n// getViaB() -> 0\n// setViaA(uint256): 23 ->\n// getViaB() -> 23\n" + }, + "code_access_content.sol": { + "content": "contract D {\n bytes32 public x;\n\n constructor() {\n bytes32 codeHash;\n assembly {\n let size := codesize()\n codecopy(mload(0x40), 0, size)\n codeHash := keccak256(mload(0x40), size)\n }\n x = codeHash;\n }\n}\n\n\ncontract C {\n function testRuntime() public returns (bool) {\n D d = new D();\n bytes32 runtimeHash = keccak256(type(D).runtimeCode);\n bytes32 otherHash;\n uint256 size;\n assembly {\n size := extcodesize(d)\n extcodecopy(d, mload(0x40), 0, size)\n otherHash := keccak256(mload(0x40), size)\n }\n require(size == type(D).runtimeCode.length);\n require(runtimeHash == otherHash);\n return true;\n }\n\n function testCreation() public returns (bool) {\n D d = new D();\n bytes32 creationHash = keccak256(type(D).creationCode);\n require(creationHash == d.x());\n return true;\n }\n}\n// ----\n// testRuntime() -> true\n// gas legacy: 76575\n// gas legacy code: 23600\n// testCreation() -> true\n// gas legacy: 76999\n// gas legacy code: 23600\n" + }, + "code_access_padding.sol": { + "content": "contract D {\n function f() public pure returns (uint256) {\n return 7;\n }\n}\n\n\ncontract C {\n function diff() public pure returns (uint256 remainder) {\n bytes memory a = type(D).creationCode;\n bytes memory b = type(D).runtimeCode;\n assembly {\n remainder := mod(sub(b, a), 0x20)\n }\n }\n}\n// ----\n// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #\n" + }, + "typed_multi_variable_declaration.sol": { + "content": "contract C {\n struct S {\n uint256 x;\n }\n S s;\n\n function g() internal returns (uint256, S storage, uint256) {\n s.x = 7;\n return (1, s, 2);\n }\n\n function f() public returns (bool) {\n (uint256 x1, S storage y1, uint256 z1) = g();\n if (x1 != 1 || y1.x != 7 || z1 != 2) return false;\n (, S storage y2, ) = g();\n if (y2.x != 7) return false;\n (uint256 x2, , ) = g();\n if (x2 != 1) return false;\n (, , uint256 z2) = g();\n if (z2 != 2) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "value_complex.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public payable returns (uint256 bal) {\n uint256 someStackElement = 20;\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114463\n// gas irOptimized code: 58800\n// gas legacy: 120091\n// gas legacy code: 132400\n// gas legacyOptimized: 114536\n// gas legacyOptimized code: 65800\n// sendAmount(uint256): 5 -> 8\n" + }, + "create_random.sol": { + "content": "contract C {\n function addr() external returns (address) {\n return address(this);\n }\n\n function testRunner() external returns (address a1, address a2) {\n assembly {\n // This is `return(0, 1)`. We are using a simplified/fixed initcode to avoid\n // instability due to metadata changes.\n let initcode := hex\"60016000f3\"\n mstore(0, initcode)\n\n a1 := create(0, 0, 5)\n a2 := create2(0, 0, 5, address())\n }\n }\n\n function testCalc() external returns (address a1, address a2) {\n a1 = calculateCreate(address(this), 1);\n a2 = calculateCreate2(address(this), keccak256(hex\"60016000f3\"), bytes32(uint256(uint160(address(this)))));\n }\n\n function calculateCreate(address from, uint256 nonce) private pure returns (address) {\n assert(nonce <= 127);\n bytes memory data =\n bytes.concat(hex\"d694\", bytes20(uint160(from)), nonce == 0 ? bytes1(hex\"80\") : bytes1(uint8(nonce)));\n return address(uint160(uint256(keccak256(data)))); // Take the lower 160-bits\n }\n\n function calculateCreate2(address creator, bytes32 codehash, bytes32 salt) private pure returns (address) {\n return address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), creator, salt, codehash)))));\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// addr() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// testRunner() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n// testCalc() -> 0x137aa4dfc0911524504fcd4d98501f179bc13b4a, 0x2c1c30623ddd93e0b765a6caaca0c859eeb0644d\n" + }, + "negative_stack_height.sol": { + "content": "contract C {\n mapping(uint256 => Invoice) public invoices;\n struct Invoice {\n uint256 AID;\n bool Aboola;\n bool Aboolc;\n bool exists;\n }\n\n function nredit(uint256 startindex)\n public\n pure\n returns (\n uint256[500] memory CIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Cboolas,\n uint256[500] memory amounts\n )\n {}\n\n function return500InvoicesByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory AIDs,\n bool[500] memory Aboolas,\n uint256[500] memory dates,\n bytes32[3][500] memory Abytesas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Aboolbs,\n bool[500] memory Aboolcs\n )\n {}\n\n function return500PaymentsByDates(\n uint256 begindate,\n uint256 enddate,\n uint256 startindex\n )\n public\n view\n returns (\n uint256[500] memory BIDs,\n uint256[500] memory dates,\n uint256[500] memory RIDs,\n bool[500] memory Bboolas,\n bytes32[3][500] memory bytesbs,\n bytes32[2][500] memory bytescs,\n uint256[500] memory amounts,\n bool[500] memory Bboolbs\n )\n {}\n}\n\n// via yul disabled because of stack issues.\n\n// ====\n// compileViaYul: false\n// ----\n// constructor() ->\n// gas legacy: 92268\n// gas legacy code: 483000\n// gas legacyOptimized: 75022\n// gas legacyOptimized code: 270000\n" + }, + "selfdestruct_post_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exist in the test below\n // when the call to selfdestruct is executed in a transaction\n // different from the one in which the contract was created.\n // However, it should still send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n // NOTE: A second call to `c.terminate()` or any other function of the contract `c` will succeed if the\n // previous selfdestruct was performed in a different transaction, since the contract will still exists.\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76227\n// gas legacy code: 298200\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// terminate() ->\n" + }, + "many_subassemblies.sol": { + "content": "contract C0 {}\ncontract C1 {}\ncontract C2 {}\ncontract C3 {}\ncontract C4 {}\ncontract C5 {}\ncontract C6 {}\ncontract C7 {}\ncontract C8 {}\ncontract C9 {}\ncontract C10 {}\n\ncontract D {\n function run() public {\n // This is primarily meant to test assembly import via --import-asm-json.\n // The exported JSON will fail the reimport unless the subassembly indices are parsed\n // correctly - as hex numbers.\n new C0();\n new C1();\n new C2();\n new C3();\n new C4();\n new C5();\n new C6();\n new C7();\n new C8();\n new C9();\n new C10();\n }\n}\n// ----\n// run() ->\n// gas irOptimized: 374934\n// gas irOptimized code: 6600\n// gas legacy: 375119\n// gas legacy code: 17600\n// gas legacyOptimized: 375119\n// gas legacyOptimized code: 17600\n" + }, + "super_parentheses.sol": { + "content": "contract A {\n function f() public virtual returns (uint256 r) {\n return 1;\n }\n}\n\n\ncontract B is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 2;\n }\n}\n\n\ncontract C is A {\n function f() public virtual override returns (uint256 r) {\n return ((super).f)() | 4;\n }\n}\n\n\ncontract D is B, C {\n function f() public override(B, C) returns (uint256 r) {\n return ((super).f)() | 8;\n }\n}\n// ----\n// f() -> 15\n" + }, + "selfdestruct_post_cancun_multiple_beneficiaries.sol": { + "content": "contract C {\n constructor() payable {}\n function terminate(address _beneficiary) public {\n selfdestruct(payable(_beneficiary));\n assert(false);\n }\n}\n\ncontract D {\n address account1 = payable(0x1111111111111111111111111111111111111111);\n address account2 = payable(0x2222222222222222222222222222222222222222);\n C public c;\n\n constructor() payable {}\n\n function deploy() public payable {\n c = new C{value: 1 ether}();\n }\n\n function terminate(address _beneficiary) public {\n c.terminate(_beneficiary);\n }\n\n function test_deploy_and_terminate_twice() public {\n deploy();\n terminate(account1);\n terminate(account2);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 2 ether ->\n// gas irOptimized: 108104\n// gas irOptimized code: 119200\n// gas legacy: 120439\n// gas legacy code: 253800\n// gas legacyOptimized: 109015\n// gas legacyOptimized code: 130800\n// balance: 0x1111111111111111111111111111111111111111 -> 0\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 2000000000000000000\n// exists() -> false\n// test_deploy_and_terminate_twice() ->\n// gas irOptimized: 121395\n// gas irOptimized code: 14000\n// gas legacy: 122386\n// gas legacy code: 43200\n// gas legacyOptimized: 121596\n// gas legacyOptimized code: 22800\n// exists() -> false\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 1000000000000000000\n// deploy() ->\n// gas legacy: 58491\n// gas legacy code: 43200\n// exists() -> true\n// balance: 0x1111111111111111111111111111111111111111 -> 1000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// terminate(address): 0x1111111111111111111111111111111111111111 ->\n// balance: 0x1111111111111111111111111111111111111111 -> 2000000000000000000\n// balance: 0x2222222222222222222222222222222222222222 -> 0\n// balance -> 0\n// exists() -> true\n" + }, + "super_alone.sol": { + "content": "contract A {\n function f() public {\n super;\n }\n}\n// ----\n// f() ->\n" + }, + "selfdestruct_post_cancun_redeploy.sol": { + "content": "contract Factory {\n event Deployed(address, bytes32);\n\n function deploy(bytes32 _salt) external payable returns (address implAddr) {\n // NOTE: The bytecode of contract C is used here instead of `type(C).creationCode` since the address calculation depends on the precise init code\n // and that will change in our test framework between legacy and via-IR codegen and via optimized vs non-optimized.\n //contract C {\n // constructor() payable {}\n // function terminate() external {\n // selfdestruct(payable(msg.sender));\n // }\n //}\n bytes memory initCode =\n hex\"6080806040526068908160108239f3fe6004361015600b575f80fd5b5f3560e0\"\n hex\"1c630c08bf8814601d575f80fd5b34602e575f366003190112602e5733ff5b5f\"\n hex\"80fdfea2646970667358221220fe3c4fe66c1838016e2efdc5b65538e5ff3dbf\"\n hex\"ced7eff135da3556db4bd841aa64736f6c63430008180033\";\n\n address target = address(uint160(uint256(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n _salt,\n keccak256(abi.encodePacked(initCode))\n )))));\n\n assembly {\n implAddr := create2(callvalue(), add(initCode, 0x20), mload(initCode), _salt)\n if iszero(extcodesize(implAddr)) {\n revert(0, 0)\n }\n }\n assert(address(implAddr) == target);\n emit Deployed(implAddr, _salt);\n }\n}\n\ninterface IC {\n function terminate() external;\n}\n\ncontract D {\n Factory public factory = new Factory();\n IC public c;\n\n constructor() payable {}\n\n function deploy_create2() public payable {\n // NOTE: `create2` cannot be used anymore to redeploy a contract in the same place to make it upgradable\n // if not performed in the same transaction.\n // Therefore, an attempt to redeploy using `create2` in a different transaction must revert for EVM >= Cancun.\n c = IC(factory.deploy{value: 1 ether}(hex\"1234\"));\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_deploy_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n\n// ====\n// EVMVersion: >=cancun\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 132974\n// gas irOptimized code: 293800\n// gas legacy: 151236\n// gas legacy code: 533800\n// gas legacyOptimized: 131436\n// gas legacyOptimized code: 276600\n// exists() -> false\n// test_deploy_and_terminate() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// gas irOptimized: 96528\n// gas irOptimized code: 20800\n// gas legacy: 97788\n// gas legacy code: 20800\n// gas legacyOptimized: 96043\n// gas legacyOptimized code: 20800\n// exists() -> false\n// deploy_create2() ->\n// ~ emit Deployed(address,bytes32) from 0x137aa4dfc0911524504fcd4d98501f179bc13b4a: 0x7e6580007e709ac52945fae182c61131d42634e8, 0x1234000000000000000000000000000000000000000000000000000000000000\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> true\n// deploy_create2() -> FAILURE\n// gas irOptimized: 96903654\n// gas legacy: 96903658\n// gas legacyOptimized: 96903639\n" + }, + "address_code_complex.sol": { + "content": "contract A {\n constructor() {\n assembly {\n // This is only 7 bytes here.\n mstore(0, 0x48aa5566000000)\n return(0, 32)\n }\n }\n}\n\ncontract C {\n function f() public returns (bytes memory) { return address(new A()).code; }\n function g() public returns (uint) { return address(new A()).code.length; }\n}\n// ----\n// f() -> 0x20, 0x20, 0x48aa5566000000\n// g() -> 0x20\n" + }, + "positive_integers_to_signed.sol": { + "content": "contract test {\n int8 public x = 2;\n int8 public y = 127;\n int16 public q = 250;\n}\n// ----\n// x() -> 2\n// y() -> 127\n// q() -> 250\n" + }, + "gasleft_decrease.sol": { + "content": "contract C {\n uint256 v;\n\n function f() public returns (bool) {\n uint256 startGas = gasleft();\n v++;\n assert(startGas > gasleft());\n return true;\n }\n\n function g() public returns (bool) {\n uint256 startGas = gasleft();\n assert(startGas > gasleft());\n return true;\n }\n}\n// ----\n// f() -> true\n// g() -> true\n" + }, + "nested_calldata_struct_to_memory.sol": { + "content": "pragma abicoder v2;\n\n\ncontract C {\n struct S1 {\n uint256 a;\n uint256 b;\n }\n struct S2 {\n uint256 a;\n uint256 b;\n S1 s;\n uint256 c;\n }\n\n function f(S2 calldata s)\n external\n pure\n returns (uint256 a, uint256 b, uint256 sa, uint256 sb, uint256 c)\n {\n S2 memory m = s;\n return (m.a, m.b, m.s.a, m.s.b, m.c);\n }\n}\n// ----\n// f((uint256,uint256,(uint256,uint256),uint256)): 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\n" + }, + "balance.sol": { + "content": "contract test {\n constructor() payable {}\n\n function getBalance() public returns (uint256 balance) {\n return address(this).balance;\n }\n}\n// ----\n// constructor(), 23 wei ->\n// getBalance() -> 23\n" + }, + "iszero_bnot_correct.sol": { + "content": "// A long time ago, some opcodes were renamed, which involved the opcodes\n// \"iszero\" and \"not\".\ncontract C {\n function f() public returns (bool) {\n bytes32 x = bytes32(uint256(1));\n assembly {\n x := not(x)\n }\n if (x != ~bytes32(uint256(1))) return false;\n assembly {\n x := iszero(x)\n }\n if (x != bytes32(0)) return false;\n return true;\n }\n}\n// ----\n// f() -> true\n" + }, + "selfdestruct_pre_cancun.sol": { + "content": "contract C {\n constructor() payable {}\n\n function terminate() external {\n // NOTE: The contract `c` should still exists in the test below,\n // since the call to the selfdestruct method was done in a tx that is\n // not the same tx that the contract was created.\n // However, it should send all Ether in `c` to the beneficiary.\n selfdestruct(payable(msg.sender));\n assert(false);\n }\n}\n\ncontract D {\n C public c;\n\n constructor() payable {}\n\n function deploy_create() public payable {\n c = new C{value: 1 ether}();\n }\n\n function deploy_create2() public payable {\n c = new C{value: 1 ether, salt: hex\"1234\"}();\n }\n\n function terminate() public {\n c.terminate();\n }\n\n function test_create_and_terminate() public {\n deploy_create();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_create2_and_terminate() public {\n deploy_create2();\n assert(exists());\n test_balance_after_create();\n terminate();\n test_balance_after_selfdestruct();\n }\n\n function test_balance_after_create() public view {\n assert(address(this).balance == 0);\n assert(address(c).balance == 1 ether);\n }\n\n function test_balance_after_selfdestruct() public view {\n assert(address(this).balance == 1 ether);\n assert(address(c).balance == 0);\n }\n\n function exists() public view returns (bool) {\n return address(c).code.length != 0;\n }\n}\n// ====\n// EVMVersion: =shanghai\n// ----\n// constructor(), 1 ether ->\n// gas irOptimized: 67028\n// gas irOptimized code: 175400\n// gas legacy: 76163\n// gas legacy code: 297400\n// gas legacyOptimized: 66516\n// gas legacyOptimized code: 168000\n// exists() -> false\n// test_create_and_terminate() ->\n// exists() -> false\n// terminate() -> FAILURE\n// deploy_create() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// test_create2_and_terminate() ->\n// exists() -> false\n// deploy_create2() ->\n// test_balance_after_create() ->\n// exists() -> true\n// terminate() ->\n// test_balance_after_selfdestruct() ->\n// exists() -> false\n// terminate() -> FAILURE\n" + }, + "inline_member_init_inheritence.sol": { + "content": "contract Base {\n constructor() {}\n\n uint256 m_base = 5;\n\n function getBMember() public returns (uint256 i) {\n return m_base;\n }\n}\n\n\ncontract Derived is Base {\n constructor() {}\n\n uint256 m_derived = 6;\n\n function getDMember() public returns (uint256 i) {\n return m_derived;\n }\n}\n// ----\n// getBMember() -> 5\n// getDMember() -> 6\n" + }, + "staticcall_for_view_and_pure.sol": { + "content": "contract C {\n uint256 x;\n\n function f() public returns (uint256) {\n x = 3;\n return 1;\n }\n}\n\n\ninterface CView {\n function f() external view returns (uint256);\n}\n\n\ninterface CPure {\n function f() external pure returns (uint256);\n}\n\n\ncontract D {\n function f() public returns (uint256) {\n return (new C()).f();\n }\n\n function fview() public returns (uint256) {\n return (CView(address(new C()))).f();\n }\n\n function fpure() public returns (uint256) {\n return (CPure(address(new C()))).f();\n }\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f() -> 0x1 # This should work, next should throw #\n// gas legacy: 76495\n// gas legacy code: 25600\n// fview() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n// fpure() -> FAILURE\n// gas irOptimized: 98425388\n// gas irOptimized code: 13200\n// gas legacy: 98413173\n// gas legacy code: 25600\n// gas legacyOptimized: 98425379\n// gas legacyOptimized code: 13200\n" + }, + "value_insane.sol": { + "content": "contract helper {\n function getBalance() public payable returns (uint256 myBalance) {\n return address(this).balance;\n }\n}\n\n\ncontract test {\n helper h;\n\n constructor() payable {\n h = new helper();\n }\n\n function sendAmount(uint256 amount) public returns (uint256 bal) {\n return h.getBalance{value: amount + 3, gas: 1000}();\n }\n}\n// ----\n// constructor(), 20 wei ->\n// gas irOptimized: 114527\n// gas irOptimized code: 59600\n// gas legacy: 120199\n// gas legacy code: 133600\n// gas legacyOptimized: 114568\n// gas legacyOptimized code: 66200\n// sendAmount(uint256): 5 -> 8\n" + }, + "code_access_runtime.sol": { + "content": "contract D {\n uint256 x;\n\n constructor() {\n x = 7;\n }\n\n function f() public view returns (uint256) {\n return x;\n }\n}\n\ncontract C {\n function test() public returns (uint256) {\n D d = new D();\n bytes32 hash;\n assembly { hash := extcodehash(d) }\n assert(hash == keccak256(type(D).runtimeCode));\n return 42;\n }\n}\n// ====\n// EVMVersion: >=constantinople\n// ----\n// test() -> 42\n// gas legacy: 76034\n// gas legacy code: 24200\n" + }, + "inline_tuple_with_rational_numbers.sol": { + "content": "contract c {\n function f() public returns (int8) {\n int8[5] memory foo3 = [int8(1), -1, 0, 0, 0];\n return foo3[0];\n }\n}\n// ----\n// f() -> 1\n" + }, + "write_storage_external.sol": { + "content": "contract C {\n uint256 public x;\n\n function f(uint256 y) public payable {\n x = y;\n }\n\n function g(uint256 y) external {\n x = y;\n }\n\n function h() public {\n this.g(12);\n }\n}\n\n\ncontract D {\n C c = new C();\n\n function f() public payable returns (uint256) {\n c.g(3);\n return c.x();\n }\n\n function g() public returns (uint256) {\n c.g(8);\n return c.x();\n }\n\n function h() public returns (uint256) {\n c.h();\n return c.x();\n }\n}\n// ----\n// f() -> 3\n// g() -> 8\n// h() -> 12\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_assert/assert.sol b/examples/test/semanticTests/viaYul_assert/assert.sol new file mode 100644 index 00000000..bd1cabc4 --- /dev/null +++ b/examples/test/semanticTests/viaYul_assert/assert.sol @@ -0,0 +1,20 @@ +contract C { + function f(bool a) public pure returns (bool x) { + bool b = a; + x = b; + assert(b); + } + function fail() public pure returns (bool x) { + x = true; + assert(false); + } + function succeed() public pure returns (bool x) { + x = true; + assert(true); + } +} +// ---- +// f(bool): true -> true +// f(bool): false -> FAILURE, hex"4e487b71", 0x01 +// fail() -> FAILURE, hex"4e487b71", 0x01 +// succeed() -> true diff --git a/examples/test/semanticTests/viaYul_assert/assert_standard_input.json b/examples/test/semanticTests/viaYul_assert/assert_standard_input.json new file mode 100644 index 00000000..19d6d4c3 --- /dev/null +++ b/examples/test/semanticTests/viaYul_assert/assert_standard_input.json @@ -0,0 +1,142 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_assert_and_require/assert_and_require.sol b/examples/test/semanticTests/viaYul_assert_and_require/assert_and_require.sol new file mode 100644 index 00000000..a403b5d6 --- /dev/null +++ b/examples/test/semanticTests/viaYul_assert_and_require/assert_and_require.sol @@ -0,0 +1,17 @@ +contract C { + function f(bool a) public pure returns (bool x) { + bool b = a; + x = b; + assert(b); + } + function f2(bool a) public pure returns (bool x) { + bool b = a; + x = b; + require(b); + } +} +// ---- +// f(bool): true -> true +// f(bool): false -> FAILURE, hex"4e487b71", 0x01 +// f2(bool): true -> true +// f2(bool): false -> FAILURE diff --git a/examples/test/semanticTests/viaYul_assert_and_require/assert_and_require_standard_input.json b/examples/test/semanticTests/viaYul_assert_and_require/assert_and_require_standard_input.json new file mode 100644 index 00000000..31c35e2f --- /dev/null +++ b/examples/test/semanticTests/viaYul_assert_and_require/assert_and_require_standard_input.json @@ -0,0 +1,205 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call.sol b/examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call.sol new file mode 100644 index 00000000..5da58b31 --- /dev/null +++ b/examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call.sol @@ -0,0 +1,14 @@ +contract C { + function f() public pure returns (uint, uint, uint) { + return (1, 2, 3); + } + function g() public pure returns (uint a, uint b, uint c) { + (c, b, a) = f(); + } + function h() public pure returns (uint a) { + (,,a) = f(); + } +} +// ---- +// g() -> 3, 2, 1 +// h() -> 3 diff --git a/examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call_standard_input.json b/examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call_standard_input.json new file mode 100644 index 00000000..c9ffc568 --- /dev/null +++ b/examples/test/semanticTests/viaYul_assign_tuple_from_function_call/assign_tuple_from_function_call_standard_input.json @@ -0,0 +1,172 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic.sol b/examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic.sol new file mode 100644 index 00000000..19b7cb84 --- /dev/null +++ b/examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic.sol @@ -0,0 +1,65 @@ +contract C { + function add() public pure returns (uint8, uint8) { + uint8 x; uint8 y = 0; + assembly { x := 0x0101 } + return (x + y, y + x); + } + function sub() public pure returns (uint8, uint8) { + uint8 x; uint8 y = 1; + assembly { x := 0x0101 } + return (x - y, y - x); + } + function mul() public pure returns (uint8, uint8) { + uint8 x; uint8 y = 1; + assembly { x := 0x0101 } + return (x * y, y * x); + } + function div() public pure returns (uint8, uint8) { + uint8 x; uint8 y = 1; + assembly { x := 0x0101 } + return (x / y, y / x); + } + function mod() public pure returns (uint8, uint8) { + uint8 x; uint8 y = 2; + assembly { x := 0x0101 } + return (x % y, y % x); + } + function inc_pre() public pure returns (uint8) { + uint8 x; + assembly { x := 0x0100 } + return ++x; + } + function inc_post() public pure returns (uint8) { + uint8 x; + assembly { x := 0x0100 } + return x++; + } + function dec_pre() public pure returns (uint8) { + uint8 x; + assembly { x := not(0xFF) } + return --x; + } + function dec_post() public pure returns (uint8) { + uint8 x; + assembly { x := not(0xFF) } + return x--; + } + function neg() public pure returns (int8) { + int8 x; + assembly { x := 0x80 } + return -x; + } +} +// ==== +// compileViaYul: true +// ---- +// add() -> 1, 1 +// sub() -> 0, 0 +// mul() -> 1, 1 +// div() -> 1, 1 +// mod() -> 1, 0 +// inc_pre() -> 1 +// inc_post() -> 0 +// dec_pre() -> FAILURE, hex"4e487b71", 0x11 +// dec_post() -> FAILURE, hex"4e487b71", 0x11 +// neg() -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic_standard_input.json b/examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic_standard_input.json new file mode 100644 index 00000000..84edd97b --- /dev/null +++ b/examples/test/semanticTests/viaYul_cleanup_checked_arithmetic/checked_arithmetic_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "comparison.sol": { + "content": "contract C {\n\tfunction eq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x == y);\n\t}\n\tfunction neq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x != y);\n\t}\n\tfunction geq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x >= y);\n\t}\n\tfunction leq() public pure returns (bool) {\n\t\tuint8 x = 2; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x <= y);\n\t}\n\tfunction gt() public pure returns (bool) {\n\t\tuint8 x = 2; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x > y);\n\t}\n\tfunction lt() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x < y);\n\t}\n}\n// ----\n// eq() -> true\n// neq() -> false\n// geq() -> true\n// leq() -> false\n// gt() -> true\n// lt() -> false\n" + }, + "checked_arithmetic.sol": { + "content": "contract C {\n\tfunction add() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 0;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x + y, y + x);\n\t}\n\tfunction sub() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 1;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x - y, y - x);\n\t}\n\tfunction mul() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 1;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x * y, y * x);\n\t}\n\tfunction div() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 1;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x / y, y / x);\n\t}\n\tfunction mod() public pure returns (uint8, uint8) {\n\t\tuint8 x; uint8 y = 2;\n\t\tassembly { x := 0x0101 }\n\t\treturn (x % y, y % x);\n\t}\n\tfunction inc_pre() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := 0x0100 }\n\t\treturn ++x;\n\t}\n\tfunction inc_post() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := 0x0100 }\n\t\treturn x++;\n\t}\n\tfunction dec_pre() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := not(0xFF) }\n\t\treturn --x;\n\t}\n\tfunction dec_post() public pure returns (uint8) {\n\t\tuint8 x;\n\t\tassembly { x := not(0xFF) }\n\t\treturn x--;\n\t}\n\tfunction neg() public pure returns (int8) {\n\t\tint8 x;\n\t\tassembly { x := 0x80 }\n\t\treturn -x;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// add() -> 1, 1\n// sub() -> 0, 0\n// mul() -> 1, 1\n// div() -> 1, 1\n// mod() -> 1, 0\n// inc_pre() -> 1\n// inc_post() -> 0\n// dec_pre() -> FAILURE, hex\"4e487b71\", 0x11\n// dec_post() -> FAILURE, hex\"4e487b71\", 0x11\n// neg() -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_cleanup_comparison/comparison.sol b/examples/test/semanticTests/viaYul_cleanup_comparison/comparison.sol new file mode 100644 index 00000000..035c2690 --- /dev/null +++ b/examples/test/semanticTests/viaYul_cleanup_comparison/comparison.sol @@ -0,0 +1,39 @@ +contract C { + function eq() public pure returns (bool) { + uint8 x = 1; uint8 y; + assembly { y := 0x0101 } + return (x == y); + } + function neq() public pure returns (bool) { + uint8 x = 1; uint8 y; + assembly { y := 0x0101 } + return (x != y); + } + function geq() public pure returns (bool) { + uint8 x = 1; uint8 y; + assembly { y := 0x0101 } + return (x >= y); + } + function leq() public pure returns (bool) { + uint8 x = 2; uint8 y; + assembly { y := 0x0101 } + return (x <= y); + } + function gt() public pure returns (bool) { + uint8 x = 2; uint8 y; + assembly { y := 0x0101 } + return (x > y); + } + function lt() public pure returns (bool) { + uint8 x = 1; uint8 y; + assembly { y := 0x0101 } + return (x < y); + } +} +// ---- +// eq() -> true +// neq() -> false +// geq() -> true +// leq() -> false +// gt() -> true +// lt() -> false diff --git a/examples/test/semanticTests/viaYul_cleanup_comparison/comparison_standard_input.json b/examples/test/semanticTests/viaYul_cleanup_comparison/comparison_standard_input.json new file mode 100644 index 00000000..84738646 --- /dev/null +++ b/examples/test/semanticTests/viaYul_cleanup_comparison/comparison_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "comparison.sol": { + "content": "contract C {\n\tfunction eq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x == y);\n\t}\n\tfunction neq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x != y);\n\t}\n\tfunction geq() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x >= y);\n\t}\n\tfunction leq() public pure returns (bool) {\n\t\tuint8 x = 2; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x <= y);\n\t}\n\tfunction gt() public pure returns (bool) {\n\t\tuint8 x = 2; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x > y);\n\t}\n\tfunction lt() public pure returns (bool) {\n\t\tuint8 x = 1; uint8 y;\n\t\tassembly { y := 0x0101 }\n\t\treturn (x < y);\n\t}\n}\n// ----\n// eq() -> true\n// neq() -> false\n// geq() -> true\n// leq() -> false\n// gt() -> true\n// lt() -> false\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_comparison/comparison.sol b/examples/test/semanticTests/viaYul_comparison/comparison.sol new file mode 100644 index 00000000..1ac2aec1 --- /dev/null +++ b/examples/test/semanticTests/viaYul_comparison/comparison.sol @@ -0,0 +1,72 @@ +contract C { + function f(address a) public pure returns (bool) { + return a == address(0); + } + function g() public pure returns (bool) { + return bytes3("abc") == bytes4("abc"); + } + function lt(uint a, uint b) public pure returns (bool) { + return a < b; + } + function slt(int a, int b) public pure returns (bool) { + return a < b; + } + function lte(uint a, uint b) public pure returns (bool) { + return a <= b; + } + function slte(int a, int b) public pure returns (bool) { + return a <= b; + } + function gt(uint a, uint b) public pure returns (bool) { + return a > b; + } + function sgt(int a, int b) public pure returns (bool) { + return a > b; + } + function gte(uint a, uint b) public pure returns (bool) { + return a >= b; + } + function sgte(int a, int b) public pure returns (bool) { + return a >= b; + } + function eq(uint a, uint b) public pure returns (bool) { + return a == b; + } + function neq(uint a, uint b) public pure returns (bool) { + return a != b; + } +} +// ---- +// f(address): 0x1234 -> false +// f(address): 0x00 -> true +// g() -> true +// lt(uint256,uint256): 4, 5 -> true +// lt(uint256,uint256): 5, 5 -> false +// lt(uint256,uint256): 6, 5 -> false +// gt(uint256,uint256): 4, 5 -> false +// gt(uint256,uint256): 5, 5 -> false +// gt(uint256,uint256): 6, 5 -> true +// lte(uint256,uint256): 4, 5 -> true +// lte(uint256,uint256): 5, 5 -> true +// lte(uint256,uint256): 6, 5 -> false +// gte(uint256,uint256): 4, 5 -> false +// gte(uint256,uint256): 5, 5 -> true +// gte(uint256,uint256): 6, 5 -> true +// eq(uint256,uint256): 4, 5 -> false +// eq(uint256,uint256): 5, 5 -> true +// eq(uint256,uint256): 6, 5 -> false +// neq(uint256,uint256): 4, 5 -> true +// neq(uint256,uint256): 5, 5 -> false +// neq(uint256,uint256): 6, 5 -> true +// slt(int256,int256): -1, 0 -> true +// slt(int256,int256): 0, 0 -> false +// slt(int256,int256): 1, 0 -> false +// sgt(int256,int256): -1, 0 -> false +// sgt(int256,int256): 0, 0 -> false +// sgt(int256,int256): 1, 0 -> true +// slte(int256,int256): -1, 0 -> true +// slte(int256,int256): 0, 0 -> true +// slte(int256,int256): 1, 0 -> false +// sgte(int256,int256): -1, 0 -> false +// sgte(int256,int256): 0, 0 -> true +// sgte(int256,int256): 1, 0 -> true diff --git a/examples/test/semanticTests/viaYul_comparison/comparison_standard_input.json b/examples/test/semanticTests/viaYul_comparison/comparison_standard_input.json new file mode 100644 index 00000000..0ada9094 --- /dev/null +++ b/examples/test/semanticTests/viaYul_comparison/comparison_standard_input.json @@ -0,0 +1,88 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_comparison_functions/comparison_functions.sol b/examples/test/semanticTests/viaYul_comparison_functions/comparison_functions.sol new file mode 100644 index 00000000..a004299b --- /dev/null +++ b/examples/test/semanticTests/viaYul_comparison_functions/comparison_functions.sol @@ -0,0 +1,29 @@ +contract C { + // If these two functions are identical, the optimiser + // on the old codegen path can deduplicate them, and breaking the test. + function internal1() internal pure returns (bool) { + return true; + } + function internal2() internal pure returns (bool) { + return false; + } + + function equal() public pure returns (bool same, bool diff, bool inv) { + function() internal pure returns (bool) invalid; + delete invalid; + same = internal1 == internal1; + diff = internal1 == internal2; + inv = internal1 == invalid; + } + + function unequal() public pure returns (bool same, bool diff, bool inv) { + function() internal pure returns (bool) invalid; + delete invalid; + same = internal1 != internal1; + diff = internal1 != internal2; + inv = internal1 != invalid; + } +} +// ---- +// equal() -> true, false, false +// unequal() -> false, true, true diff --git a/examples/test/semanticTests/viaYul_comparison_functions/comparison_functions_standard_input.json b/examples/test/semanticTests/viaYul_comparison_functions/comparison_functions_standard_input.json new file mode 100644 index 00000000..53f04995 --- /dev/null +++ b/examples/test/semanticTests/viaYul_comparison_functions/comparison_functions_standard_input.json @@ -0,0 +1,190 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple.sol b/examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple.sol new file mode 100644 index 00000000..828398f5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple.sol @@ -0,0 +1,8 @@ +contract A { + function f() public pure returns (uint) { + uint x = 3 < 0 ? 2 > 1 ? 2 : 1 : 7 > 2 ? 7 : 6; + return x; + } +} +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple_standard_input.json b/examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple_standard_input.json new file mode 100644 index 00000000..b7e5d81a --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_multiple/conditional_multiple_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "conditional_with_assignment.sol": { + "content": "contract A {\n function f() public pure returns (uint, uint, uint, uint) {\n\t\tuint y1 = 1;\n\t\tuint y2 = 1;\n\t\tuint x = 3 < 0 ? y1 = 3 : 6;\n\t\tuint z = 3 < 10 ? y2 = 5 : 6;\n\t\treturn (x, y1, y2, z);\n\t}\n}\n// ----\n// f() -> 6, 1, 5, 5\n" + }, + "conditional_tuple.sol": { + "content": "contract A {\n\tfunction f(bool cond) public pure returns (uint, uint) {\n\t\t(uint a, uint b) = cond ? (1, 2) : (3, 4);\n\t\treturn (a, b);\n\t}\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "conditional_true_false_literal.sol": { + "content": "contract A {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = true ? 1 : 0;\n\t\tuint y = false ? 0 : 1;\n\t\treturn x + y;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "conditional_with_variables.sol": { + "content": "contract A {\n\tfunction f() public pure returns (uint, uint, uint, uint) {\n\t\tuint x = 3;\n\t\tuint y = 1;\n\t\tuint z = (x > y) ? x : y;\n\t\tuint w = x < y ? x : y;\n\t\treturn (x, y, z, w);\n\t}\n}\n// ----\n// f() -> 3, 1, 3, 1\n" + }, + "conditional_multiple.sol": { + "content": "contract A {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = 3 < 0 ? 2 > 1 ? 2 : 1 : 7 > 2 ? 7 : 6;\n\t\treturn x;\n\t}\n}\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal.sol b/examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal.sol new file mode 100644 index 00000000..c2bbb08d --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal.sol @@ -0,0 +1,9 @@ +contract A { + function f() public pure returns (uint) { + uint x = true ? 1 : 0; + uint y = false ? 0 : 1; + return x + y; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal_standard_input.json b/examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal_standard_input.json new file mode 100644 index 00000000..f9850a43 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_true_false_literal/conditional_true_false_literal_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "conditional_with_assignment.sol": { + "content": "contract A {\n function f() public pure returns (uint, uint, uint, uint) {\n\t\tuint y1 = 1;\n\t\tuint y2 = 1;\n\t\tuint x = 3 < 0 ? y1 = 3 : 6;\n\t\tuint z = 3 < 10 ? y2 = 5 : 6;\n\t\treturn (x, y1, y2, z);\n\t}\n}\n// ----\n// f() -> 6, 1, 5, 5\n" + }, + "conditional_tuple.sol": { + "content": "contract A {\n\tfunction f(bool cond) public pure returns (uint, uint) {\n\t\t(uint a, uint b) = cond ? (1, 2) : (3, 4);\n\t\treturn (a, b);\n\t}\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "conditional_true_false_literal.sol": { + "content": "contract A {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = true ? 1 : 0;\n\t\tuint y = false ? 0 : 1;\n\t\treturn x + y;\n\t}\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple.sol b/examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple.sol new file mode 100644 index 00000000..51030f9a --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple.sol @@ -0,0 +1,9 @@ +contract A { + function f(bool cond) public pure returns (uint, uint) { + (uint a, uint b) = cond ? (1, 2) : (3, 4); + return (a, b); + } +} +// ---- +// f(bool): true -> 1, 2 +// f(bool): false -> 3, 4 diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple_standard_input.json b/examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple_standard_input.json new file mode 100644 index 00000000..26292932 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_tuple/conditional_tuple_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "conditional_with_assignment.sol": { + "content": "contract A {\n function f() public pure returns (uint, uint, uint, uint) {\n\t\tuint y1 = 1;\n\t\tuint y2 = 1;\n\t\tuint x = 3 < 0 ? y1 = 3 : 6;\n\t\tuint z = 3 < 10 ? y2 = 5 : 6;\n\t\treturn (x, y1, y2, z);\n\t}\n}\n// ----\n// f() -> 6, 1, 5, 5\n" + }, + "conditional_tuple.sol": { + "content": "contract A {\n\tfunction f(bool cond) public pure returns (uint, uint) {\n\t\t(uint a, uint b) = cond ? (1, 2) : (3, 4);\n\t\treturn (a, b);\n\t}\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment.sol b/examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment.sol new file mode 100644 index 00000000..80d4dde6 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment.sol @@ -0,0 +1,11 @@ +contract A { + function f() public pure returns (uint, uint, uint, uint) { + uint y1 = 1; + uint y2 = 1; + uint x = 3 < 0 ? y1 = 3 : 6; + uint z = 3 < 10 ? y2 = 5 : 6; + return (x, y1, y2, z); + } +} +// ---- +// f() -> 6, 1, 5, 5 diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment_standard_input.json b/examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment_standard_input.json new file mode 100644 index 00000000..a2128cc0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_with_assignment/conditional_with_assignment_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "conditional_with_assignment.sol": { + "content": "contract A {\n function f() public pure returns (uint, uint, uint, uint) {\n\t\tuint y1 = 1;\n\t\tuint y2 = 1;\n\t\tuint x = 3 < 0 ? y1 = 3 : 6;\n\t\tuint z = 3 < 10 ? y2 = 5 : 6;\n\t\treturn (x, y1, y2, z);\n\t}\n}\n// ----\n// f() -> 6, 1, 5, 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables.sol b/examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables.sol new file mode 100644 index 00000000..4de29663 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables.sol @@ -0,0 +1,11 @@ +contract A { + function f() public pure returns (uint, uint, uint, uint) { + uint x = 3; + uint y = 1; + uint z = (x > y) ? x : y; + uint w = x < y ? x : y; + return (x, y, z, w); + } +} +// ---- +// f() -> 3, 1, 3, 1 diff --git a/examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables_standard_input.json b/examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables_standard_input.json new file mode 100644 index 00000000..f5d207d8 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conditional_conditional_with_variables/conditional_with_variables_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "conditional_with_assignment.sol": { + "content": "contract A {\n function f() public pure returns (uint, uint, uint, uint) {\n\t\tuint y1 = 1;\n\t\tuint y2 = 1;\n\t\tuint x = 3 < 0 ? y1 = 3 : 6;\n\t\tuint z = 3 < 10 ? y2 = 5 : 6;\n\t\treturn (x, y1, y2, z);\n\t}\n}\n// ----\n// f() -> 6, 1, 5, 5\n" + }, + "conditional_tuple.sol": { + "content": "contract A {\n\tfunction f(bool cond) public pure returns (uint, uint) {\n\t\t(uint a, uint b) = cond ? (1, 2) : (3, 4);\n\t\treturn (a, b);\n\t}\n}\n// ----\n// f(bool): true -> 1, 2\n// f(bool): false -> 3, 4\n" + }, + "conditional_true_false_literal.sol": { + "content": "contract A {\n\tfunction f() public pure returns (uint) {\n\t\tuint x = true ? 1 : 0;\n\t\tuint y = false ? 0 : 1;\n\t\treturn x + y;\n\t}\n}\n// ----\n// f() -> 2\n" + }, + "conditional_with_variables.sol": { + "content": "contract A {\n\tfunction f() public pure returns (uint, uint, uint, uint) {\n\t\tuint x = 3;\n\t\tuint y = 1;\n\t\tuint z = (x > y) ? x : y;\n\t\tuint w = x < y ? x : y;\n\t\treturn (x, y, z, w);\n\t}\n}\n// ----\n// f() -> 3, 1, 3, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment.sol b/examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment.sol new file mode 100644 index 00000000..cc5a156e --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure returns (uint16 x) { + uint8 y = uint8(0x78); + x = y; + } +} +// ---- +// f() -> 0x78 diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment_standard_input.json b/examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment_standard_input.json new file mode 100644 index 00000000..94fdf899 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_cast_assignment/explicit_cast_assignment_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call.sol b/examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call.sol new file mode 100644 index 00000000..0ab4b34a --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call.sol @@ -0,0 +1,10 @@ +contract C { + function f(bytes32 b) public pure returns (bytes32 x) { + x = b; + } + function g() public pure returns (bytes32 x) { + x = f(bytes4(uint32(0x12345678))); + } +} +// ---- +// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call_standard_input.json b/examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call_standard_input.json new file mode 100644 index 00000000..b27ae619 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_cast_function_call/explicit_cast_function_call_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "implicit_cast_local_assignment.sol": { + "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n function f() public pure returns (uint y) {\n uint8 a;\n assembly { a := 0x12345678 }\n uint z = a;\n y = z;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "explicit_cast_function_call.sol": { + "content": "contract C {\n function f(bytes32 b) public pure returns (bytes32 x) {\n x = b;\n }\n function g() public pure returns (bytes32 x) {\n x = f(bytes4(uint32(0x12345678)));\n }\n}\n// ----\n// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment.sol b/examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment.sol new file mode 100644 index 00000000..425c6eae --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint a) public pure returns (uint8 x) { + uint8 b = uint8(a); + x = b; + } +} +// ---- +// f(uint256): 0x12345678 -> 0x78 diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment_standard_input.json b/examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment_standard_input.json new file mode 100644 index 00000000..a108f516 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_cast_local_assignment/explicit_cast_local_assignment_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "implicit_cast_local_assignment.sol": { + "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n function f() public pure returns (uint y) {\n uint8 a;\n assembly { a := 0x12345678 }\n uint z = a;\n y = z;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "explicit_cast_function_call.sol": { + "content": "contract C {\n function f(bytes32 b) public pure returns (bytes32 x) {\n x = b;\n }\n function g() public pure returns (bytes32 x) {\n x = f(bytes4(uint32(0x12345678)));\n }\n}\n// ----\n// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000\n" + }, + "explicit_string_bytes_calldata_cast.sol": { + "content": "// Triggered ICE before\ncontract C {\n\tfunction f(string calldata data) external pure returns(string memory) {\n\t\tbytes calldata test = bytes(data[:3]);\n\t\treturn string(test);\n\t}\n}\n// ----\n// f(string): 0x20, 3, \"123\" -> 0x20, 3, \"123\"\n" + }, + "implicit_cast_function_call.sol": { + "content": "// IRGeneratorForStatements::visit(FunctionCall const& _functionCall)\ncontract C {\n function f(uint b) public pure returns (uint x) {\n x = b;\n }\n function g() public pure returns (uint x) {\n uint8 a;\n assembly {\n a := 0x12345678\n }\n x = f(a);\n }\n}\n// ----\n// g() -> 0x78\n" + }, + "explicit_cast_local_assignment.sol": { + "content": "contract C {\n function f(uint a) public pure returns (uint8 x) {\n uint8 b = uint8(a);\n x = b;\n }\n}\n// ----\n// f(uint256): 0x12345678 -> 0x78\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast.sol b/examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast.sol new file mode 100644 index 00000000..46d4492e --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast.sol @@ -0,0 +1,9 @@ +// Triggered ICE before +contract C { + function f(string calldata data) external pure returns(string memory) { + bytes calldata test = bytes(data[:3]); + return string(test); + } +} +// ---- +// f(string): 0x20, 3, "123" -> 0x20, 3, "123" diff --git a/examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast_standard_input.json b/examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast_standard_input.json new file mode 100644 index 00000000..06bd6b92 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_explicit_string_bytes_calldata_cast/explicit_string_bytes_calldata_cast_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "implicit_cast_local_assignment.sol": { + "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n function f() public pure returns (uint y) {\n uint8 a;\n assembly { a := 0x12345678 }\n uint z = a;\n y = z;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "explicit_cast_function_call.sol": { + "content": "contract C {\n function f(bytes32 b) public pure returns (bytes32 x) {\n x = b;\n }\n function g() public pure returns (bytes32 x) {\n x = f(bytes4(uint32(0x12345678)));\n }\n}\n// ----\n// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000\n" + }, + "explicit_string_bytes_calldata_cast.sol": { + "content": "// Triggered ICE before\ncontract C {\n\tfunction f(string calldata data) external pure returns(string memory) {\n\t\tbytes calldata test = bytes(data[:3]);\n\t\treturn string(test);\n\t}\n}\n// ----\n// f(string): 0x20, 3, \"123\" -> 0x20, 3, \"123\"\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_function_cast/function_cast.sol b/examples/test/semanticTests/viaYul_conversion_function_cast/function_cast.sol new file mode 100644 index 00000000..843376ba --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_function_cast/function_cast.sol @@ -0,0 +1,21 @@ +contract C { + function f(uint x) public pure returns (uint) { + return 2 * x; + } + function g() public view returns (function (uint) external returns (uint)) { + return this.f; + } + function h(uint x) public returns (uint) { + return this.g()(x) + 1; + } + function t() external view returns ( + function(uint) external returns (uint) a, + function(uint) external view returns (uint) b) { + a = this.f; + b = this.f; + } +} +// ---- +// f(uint256): 2 -> 4 +// h(uint256): 2 -> 5 +// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000 diff --git a/examples/test/semanticTests/viaYul_conversion_function_cast/function_cast_standard_input.json b/examples/test/semanticTests/viaYul_conversion_function_cast/function_cast_standard_input.json new file mode 100644 index 00000000..88ee9670 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_function_cast/function_cast_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment.sol b/examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment.sol new file mode 100644 index 00000000..e2246601 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment.sol @@ -0,0 +1,12 @@ +// Tests IRGeneratorForStatements::visit(Assignment const& _assignment) +contract C { + function f() public pure returns (uint16 x) { + uint8 y; + assembly { + y := 0x12345678 + } + x = y; + } +} +// ---- +// f() -> 0x78 diff --git a/examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment_standard_input.json b/examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment_standard_input.json new file mode 100644 index 00000000..f4419bb8 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_implicit_cast_assignment/implicit_cast_assignment_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "implicit_cast_local_assignment.sol": { + "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n function f() public pure returns (uint y) {\n uint8 a;\n assembly { a := 0x12345678 }\n uint z = a;\n y = z;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "explicit_cast_function_call.sol": { + "content": "contract C {\n function f(bytes32 b) public pure returns (bytes32 x) {\n x = b;\n }\n function g() public pure returns (bytes32 x) {\n x = f(bytes4(uint32(0x12345678)));\n }\n}\n// ----\n// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000\n" + }, + "explicit_string_bytes_calldata_cast.sol": { + "content": "// Triggered ICE before\ncontract C {\n\tfunction f(string calldata data) external pure returns(string memory) {\n\t\tbytes calldata test = bytes(data[:3]);\n\t\treturn string(test);\n\t}\n}\n// ----\n// f(string): 0x20, 3, \"123\" -> 0x20, 3, \"123\"\n" + }, + "implicit_cast_function_call.sol": { + "content": "// IRGeneratorForStatements::visit(FunctionCall const& _functionCall)\ncontract C {\n function f(uint b) public pure returns (uint x) {\n x = b;\n }\n function g() public pure returns (uint x) {\n uint8 a;\n assembly {\n a := 0x12345678\n }\n x = f(a);\n }\n}\n// ----\n// g() -> 0x78\n" + }, + "explicit_cast_local_assignment.sol": { + "content": "contract C {\n function f(uint a) public pure returns (uint8 x) {\n uint8 b = uint8(a);\n x = b;\n }\n}\n// ----\n// f(uint256): 0x12345678 -> 0x78\n" + }, + "implicit_cast_assignment.sol": { + "content": "// Tests IRGeneratorForStatements::visit(Assignment const& _assignment)\ncontract C {\n function f() public pure returns (uint16 x) {\n uint8 y;\n assembly {\n y := 0x12345678\n }\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call.sol b/examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call.sol new file mode 100644 index 00000000..e62d45b3 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call.sol @@ -0,0 +1,15 @@ +// IRGeneratorForStatements::visit(FunctionCall const& _functionCall) +contract C { + function f(uint b) public pure returns (uint x) { + x = b; + } + function g() public pure returns (uint x) { + uint8 a; + assembly { + a := 0x12345678 + } + x = f(a); + } +} +// ---- +// g() -> 0x78 diff --git a/examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call_standard_input.json b/examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call_standard_input.json new file mode 100644 index 00000000..b4c57d51 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_implicit_cast_function_call/implicit_cast_function_call_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "implicit_cast_local_assignment.sol": { + "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n function f() public pure returns (uint y) {\n uint8 a;\n assembly { a := 0x12345678 }\n uint z = a;\n y = z;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "explicit_cast_function_call.sol": { + "content": "contract C {\n function f(bytes32 b) public pure returns (bytes32 x) {\n x = b;\n }\n function g() public pure returns (bytes32 x) {\n x = f(bytes4(uint32(0x12345678)));\n }\n}\n// ----\n// g() -> 0x1234567800000000000000000000000000000000000000000000000000000000\n" + }, + "explicit_string_bytes_calldata_cast.sol": { + "content": "// Triggered ICE before\ncontract C {\n\tfunction f(string calldata data) external pure returns(string memory) {\n\t\tbytes calldata test = bytes(data[:3]);\n\t\treturn string(test);\n\t}\n}\n// ----\n// f(string): 0x20, 3, \"123\" -> 0x20, 3, \"123\"\n" + }, + "implicit_cast_function_call.sol": { + "content": "// IRGeneratorForStatements::visit(FunctionCall const& _functionCall)\ncontract C {\n function f(uint b) public pure returns (uint x) {\n x = b;\n }\n function g() public pure returns (uint x) {\n uint8 a;\n assembly {\n a := 0x12345678\n }\n x = f(a);\n }\n}\n// ----\n// g() -> 0x78\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment.sol b/examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment.sol new file mode 100644 index 00000000..3793b4e0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment.sol @@ -0,0 +1,11 @@ +// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement) +contract C { + function f() public pure returns (uint y) { + uint8 a; + assembly { a := 0x12345678 } + uint z = a; + y = z; + } +} +// ---- +// f() -> 0x78 diff --git a/examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment_standard_input.json b/examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment_standard_input.json new file mode 100644 index 00000000..37ac186e --- /dev/null +++ b/examples/test/semanticTests/viaYul_conversion_implicit_cast_local_assignment/implicit_cast_local_assignment_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "function_cast.sol": { + "content": "contract C {\n\tfunction f(uint x) public pure returns (uint) {\n\t\treturn 2 * x;\n\t}\n\tfunction g() public view returns (function (uint) external returns (uint)) {\n\t\treturn this.f;\n\t}\n\tfunction h(uint x) public returns (uint) {\n\t\treturn this.g()(x) + 1;\n\t}\n\tfunction t() external view returns (\n\t\t\tfunction(uint) external returns (uint) a,\n\t\t\tfunction(uint) external view returns (uint) b) {\n\t\ta = this.f;\n\t\tb = this.f;\n\t}\n}\n// ----\n// f(uint256): 2 -> 4\n// h(uint256): 2 -> 5\n// t() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000, 0xc06afe3a8444fc0004668591e8306bfb9968e79eb3de648b0000000000000000\n" + }, + "explicit_cast_assignment.sol": { + "content": "contract C {\n function f() public pure returns (uint16 x) {\n uint8 y = uint8(0x78);\n x = y;\n }\n}\n// ----\n// f() -> 0x78\n" + }, + "implicit_cast_local_assignment.sol": { + "content": "// IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement)\ncontract C {\n function f() public pure returns (uint y) {\n uint8 a;\n assembly { a := 0x12345678 }\n uint z = a;\n y = z;\n }\n}\n// ----\n// f() -> 0x78\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug.sol b/examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug.sol new file mode 100644 index 00000000..0db482c0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug.sol @@ -0,0 +1,26 @@ +contract C { + struct Struct { + function () external el; + } + Struct[] array; + int externalCalled = 0; + + function ext() external { + externalCalled++; + } + + function f() public { + array.push(Struct(this.ext)); + array.push(array[0]); + + array[0].el(); + array[1].el(); + + assert(externalCalled == 2); + } +} +// ---- +// f() -> +// gas irOptimized: 113117 +// gas legacy: 112888 +// gas legacyOptimized: 112580 diff --git a/examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug_standard_input.json b/examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug_standard_input.json new file mode 100644 index 00000000..4c594a09 --- /dev/null +++ b/examples/test/semanticTests/viaYul_copy_struct_invalid_ir_bug/copy_struct_invalid_ir_bug_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call.sol b/examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call.sol new file mode 100644 index 00000000..3e1559bc --- /dev/null +++ b/examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call.sol @@ -0,0 +1,16 @@ +contract C { + function f() public pure returns (uint, uint, uint) { + return (1, 2, 3); + } + function g() public pure returns (uint x, uint y, uint z) { + (uint c, uint b, uint a) = f(); + (x, y, z) = (a, b, c); + } + function h() public pure returns (uint) { + (,,uint a) = f(); + return a; + } +} +// ---- +// g() -> 3, 2, 1 +// h() -> 3 diff --git a/examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call_standard_input.json b/examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call_standard_input.json new file mode 100644 index 00000000..f6dae227 --- /dev/null +++ b/examples/test/semanticTests/viaYul_define_tuple_from_function_call/define_tuple_from_function_call_standard_input.json @@ -0,0 +1,208 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + }, + "define_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint x, uint y, uint z) {\n (uint c, uint b, uint a) = f();\n (x, y, z) = (a, b, c);\n }\n function h() public pure returns (uint) {\n (,,uint a) = f();\n return a;\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_delete/delete.sol b/examples/test/semanticTests/viaYul_delete/delete.sol new file mode 100644 index 00000000..6a0f3d59 --- /dev/null +++ b/examples/test/semanticTests/viaYul_delete/delete.sol @@ -0,0 +1,23 @@ +contract C { + function internal_func() internal pure returns (int8) + { + return 1; + } + function call_internal_func() public pure returns (bool ret) + { + function() internal pure returns(int8) func = internal_func; + + return func() == internal_func(); + } + function call_deleted_internal_func() public pure returns (bool ret) + { + function() internal pure returns(int8) func = internal_func; + + delete func; + + return func() == internal_func(); + } +} +// ---- +// call_deleted_internal_func() -> FAILURE, hex"4e487b71", 0x51 +// call_internal_func() -> true diff --git a/examples/test/semanticTests/viaYul_delete/delete_standard_input.json b/examples/test/semanticTests/viaYul_delete/delete_standard_input.json new file mode 100644 index 00000000..6111c50e --- /dev/null +++ b/examples/test/semanticTests/viaYul_delete/delete_standard_input.json @@ -0,0 +1,139 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow.sol b/examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow.sol new file mode 100644 index 00000000..412998b5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow.sol @@ -0,0 +1,16 @@ +contract C { + function f(uint a, uint b) public pure returns (uint x) { + x = a + b; + } + function g(uint8 a, uint8 b) public pure returns (uint8 x) { + x = a + b; + } +} +// ---- +// f(uint256,uint256): 5, 6 -> 11 +// f(uint256,uint256): -2, 1 -> -1 +// f(uint256,uint256): -2, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): 2, -2 -> FAILURE, hex"4e487b71", 0x11 +// g(uint8,uint8): 128, 64 -> 192 +// g(uint8,uint8): 128, 127 -> 255 +// g(uint8,uint8): 128, 128 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow_standard_input.json b/examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow_standard_input.json new file mode 100644 index 00000000..8abe09ce --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_add_overflow/detect_add_overflow_standard_input.json @@ -0,0 +1,115 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed.sol b/examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed.sol new file mode 100644 index 00000000..5c721ac2 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed.sol @@ -0,0 +1,37 @@ +contract C { + function f(int a, int b) public pure returns (int x) { + x = a + b; + } + function g(int8 a, int8 b) public pure returns (int8 x) { + x = a + b; + } +} +// ---- +// f(int256,int256): 5, 6 -> 11 +// f(int256,int256): -2, 1 -> -1 +// f(int256,int256): -2, 2 -> 0 +// f(int256,int256): 2, -2 -> 0 +// f(int256,int256): -5, -6 -> -11 +// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): 5, 6 -> 11 +// g(int8,int8): -2, 1 -> -1 +// g(int8,int8): -2, 2 -> 0 +// g(int8,int8): 2, -2 -> 0 +// g(int8,int8): -5, -6 -> -11 +// g(int8,int8): 126, 1 -> 127 +// g(int8,int8): 1, 126 -> 127 +// g(int8,int8): 127, 1 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): 1, 127 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -127, -1 -> -128 +// g(int8,int8): -1, -127 -> -128 +// g(int8,int8): -127, -2 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -2, -127 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -128, 0 -> -128 +// g(int8,int8): 0, -128 -> -128 diff --git a/examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed_standard_input.json b/examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed_standard_input.json new file mode 100644 index 00000000..3465c7eb --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_add_overflow_signed/detect_add_overflow_signed_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow.sol b/examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow.sol new file mode 100644 index 00000000..d4cefe12 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow.sol @@ -0,0 +1,25 @@ +contract C { + function f(uint a, uint b) public pure returns (uint x) { + x = a / b; + } + function g(int8 a, int8 b) public pure returns (int8 x) { + x = a / b; + } + function h(uint256 a, uint256 b) public pure returns (uint256 x) { + x = a / b; + } +} +// ---- +// f(uint256,uint256): 10, 3 -> 3 +// f(uint256,uint256): 1, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(uint256,uint256): 0, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(uint256,uint256): 0, 1 -> 0 +// g(int8,int8): -10, 3 -> -3 +// g(int8,int8): -10, -3 -> 3 +// g(int8,int8): -10, 0 -> FAILURE, hex"4e487b71", 0x12 +// g(int8,int8): -128, 1 -> -128 +// g(int8,int8): -128, -2 -> 64 +// g(int8,int8): -128, 2 -> -64 +// g(int8,int8): -128, -1 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -127, -1 -> 127 +// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0 diff --git a/examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow_standard_input.json b/examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow_standard_input.json new file mode 100644 index 00000000..af68016d --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_div_overflow/detect_div_overflow_standard_input.json @@ -0,0 +1,58 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero.sol b/examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero.sol new file mode 100644 index 00000000..0d043298 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero.sol @@ -0,0 +1,23 @@ +contract C { + function f(uint a, uint b) public pure returns (uint x) { + x = a % b; + } + function g(uint8 a, uint8 b) public pure returns (uint8 x) { + x = a % b; + } +} +// ---- +// f(uint256,uint256): 10, 3 -> 1 +// f(uint256,uint256): 10, 2 -> 0 +// f(uint256,uint256): 11, 2 -> 1 +// f(uint256,uint256): 2, 2 -> 0 +// f(uint256,uint256): 1, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(uint256,uint256): 0, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(uint256,uint256): 0, 1 -> 0 +// g(uint8,uint8): 10, 3 -> 1 +// g(uint8,uint8): 10, 2 -> 0 +// g(uint8,uint8): 11, 2 -> 1 +// g(uint8,uint8): 2, 2 -> 0 +// g(uint8,uint8): 1, 0 -> FAILURE, hex"4e487b71", 0x12 +// g(uint8,uint8): 0, 0 -> FAILURE, hex"4e487b71", 0x12 +// g(uint8,uint8): 0, 1 -> 0 diff --git a/examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero_standard_input.json b/examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero_standard_input.json new file mode 100644 index 00000000..9c5c7c08 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mod_zero/detect_mod_zero_standard_input.json @@ -0,0 +1,157 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed.sol b/examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed.sol new file mode 100644 index 00000000..e97bc4cc --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed.sol @@ -0,0 +1,35 @@ +contract C { + function f(int a, int b) public pure returns (int x) { + x = a % b; + } + function g(int8 a, int8 b) public pure returns (int8 x) { + x = a % b; + } +} +// ---- +// f(int256,int256): 10, 3 -> 1 +// f(int256,int256): 10, 2 -> 0 +// f(int256,int256): 11, 2 -> 1 +// f(int256,int256): -10, 3 -> -1 +// f(int256,int256): 10, -3 -> 1 +// f(int256,int256): -10, -3 -> -1 +// f(int256,int256): 2, 2 -> 0 +// f(int256,int256): 1, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(int256,int256): -1, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(int256,int256): 0, 0 -> FAILURE, hex"4e487b71", 0x12 +// f(int256,int256): 0, 1 -> 0 +// f(int256,int256): 0, -1 -> 0 +// g(int8,int8): 10, 3 -> 1 +// g(int8,int8): 10, 2 -> 0 +// g(int8,int8): 11, 2 -> 1 +// g(int8,int8): -10, 3 -> -1 +// g(int8,int8): 10, -3 -> 1 +// g(int8,int8): -10, -3 -> -1 +// g(int8,int8): 2, 2 -> 0 +// g(int8,int8): 1, 0 -> FAILURE, hex"4e487b71", 0x12 +// g(int8,int8): -1, 0 -> FAILURE, hex"4e487b71", 0x12 +// g(int8,int8): 0, 0 -> FAILURE, hex"4e487b71", 0x12 +// g(int8,int8): 0, 1 -> 0 +// g(int8,int8): 0, -1 -> 0 +// g(int8,int8): -128, -128 -> 0 +// g(int8,int8): -128, 127 -> -1 diff --git a/examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed_standard_input.json b/examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed_standard_input.json new file mode 100644 index 00000000..7ac3e16d --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mod_zero_signed/detect_mod_zero_signed_standard_input.json @@ -0,0 +1,112 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow.sol b/examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow.sol new file mode 100644 index 00000000..935d0375 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow.sol @@ -0,0 +1,35 @@ +contract C { + function f(uint a, uint b) public pure returns (uint x) { + x = a * b; + } + function g(uint8 a, uint8 b) public pure returns (uint8 x) { + x = a * b; + } +} +// ---- +// f(uint256,uint256): 5, 6 -> 30 +// f(uint256,uint256): -1, 1 -> -1 +// f(uint256,uint256): -1, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2 +// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2 +// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 +// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 +// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1 +// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1 +// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex"4e487b71", 0x11 +// f(uint256,uint256): -1, 0 -> 0 +// f(uint256,uint256): 0, -1 -> 0 +// g(uint8,uint8): 5, 6 -> 30 +// g(uint8,uint8): 0x80, 2 -> FAILURE, hex"4e487b71", 0x11 +// g(uint8,uint8): 0x7F, 2 -> 254 +// g(uint8,uint8): 2, 0x7F -> 254 +// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex"4e487b71", 0x11 +// g(uint8,uint8): 0x0F, 0x11 -> 0xFF +// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex"4e487b71", 0x11 +// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex"4e487b71", 0x11 +// g(uint8,uint8): 0xFF, 0 -> 0 +// g(uint8,uint8): 0, 0xFF -> 0 diff --git a/examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow_standard_input.json b/examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow_standard_input.json new file mode 100644 index 00000000..7dcc8412 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mul_overflow/detect_mul_overflow_standard_input.json @@ -0,0 +1,160 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed.sol b/examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed.sol new file mode 100644 index 00000000..213b1a6d --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed.sol @@ -0,0 +1,82 @@ +contract C { + function f(int a, int b) public pure returns (int x) { + x = a * b; + } + function g(int8 a, int8 b) public pure returns (int8 x) { + x = a * b; + } + function h(int160 a, int160 b) public pure returns (int160 x) { + x = a * b; + } +} +// ---- +// f(int256,int256): 5, 6 -> 30 +// f(int256,int256): -1, 1 -> -1 +// f(int256,int256): -1, 2 -> -2 # positive, positive # +// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 # positive, negative # +// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 # positive, negative # +// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 # positive, negative # +// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex"4e487b71", 0x11 # negative, positive # +// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex"4e487b71", 0x11 # negative, positive # +// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex"4e487b71", 0x11 # negative, positive # +// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex"4e487b71", 0x11 # negative, negative # +// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex"4e487b71", 0x11 # negative, negative # +// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex"4e487b71", 0x11 # negative, negative # +// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 # small type # +// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 # small type # +// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 # small type # +// g(int8,int8): 5, 6 -> 30 +// g(int8,int8): -1, 1 -> -1 +// g(int8,int8): -1, 2 -> -2 # positive, positive # +// g(int8,int8): 63, 2 -> 126 +// g(int8,int8): 64, 2 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): 2, 63 -> 126 +// g(int8,int8): 2, 64 -> FAILURE, hex"4e487b71", 0x11 # positive, negative # +// g(int8,int8): 2, 64 -> FAILURE, hex"4e487b71", 0x11 # positive, negative # +// g(int8,int8): 2, 64 -> FAILURE, hex"4e487b71", 0x11 # positive, negative # +// g(int8,int8): 64, -2 -> -128 +// g(int8,int8): 65, -2 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): 2, -64 -> -128 +// g(int8,int8): 2, -65 -> FAILURE, hex"4e487b71", 0x11 # negative, positive # +// g(int8,int8): 2, -65 -> FAILURE, hex"4e487b71", 0x11 # negative, positive # +// g(int8,int8): 2, -65 -> FAILURE, hex"4e487b71", 0x11 # negative, positive # +// g(int8,int8): -2, 64 -> -128 +// g(int8,int8): -2, 65 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -64, 2 -> -128 +// g(int8,int8): -65, 2 -> FAILURE, hex"4e487b71", 0x11 # negative, negative # +// g(int8,int8): -65, 2 -> FAILURE, hex"4e487b71", 0x11 # negative, negative # +// g(int8,int8): -65, 2 -> FAILURE, hex"4e487b71", 0x11 # negative, negative # +// g(int8,int8): -63, -2 -> 126 +// g(int8,int8): -64, -2 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -2, -63 -> 126 +// g(int8,int8): -2, -64 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): -1, 1 -> -1 +// h(int160,int160): 1, -1 -> -1 +// h(int160,int160): -1, 2 -> -2 +// h(int160,int160): 2, -1 -> -2 +// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 +// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 +// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex"4e487b71", 0x11 +// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed_standard_input.json b/examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed_standard_input.json new file mode 100644 index 00000000..dae25eb0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_mul_overflow_signed/detect_mul_overflow_signed_standard_input.json @@ -0,0 +1,61 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow.sol b/examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow.sol new file mode 100644 index 00000000..ee059137 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow.sol @@ -0,0 +1,15 @@ +contract C { + function f(uint a, uint b) public pure returns (uint x) { + x = a - b; + } + function g(uint8 a, uint8 b) public pure returns (uint8 x) { + x = a - b; + } +} +// ---- +// f(uint256,uint256): 6, 5 -> 1 +// f(uint256,uint256): 6, 6 -> 0 +// f(uint256,uint256): 5, 6 -> FAILURE, hex"4e487b71", 0x11 +// g(uint8,uint8): 6, 5 -> 1 +// g(uint8,uint8): 6, 6 -> 0 +// g(uint8,uint8): 5, 6 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow_standard_input.json b/examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow_standard_input.json new file mode 100644 index 00000000..dc89db63 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_sub_overflow/detect_sub_overflow_standard_input.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed.sol b/examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed.sol new file mode 100644 index 00000000..a247af68 --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed.sol @@ -0,0 +1,40 @@ +contract C { + function f(int a, int b) public pure returns (int x) { + x = a - b; + } + function g(int8 a, int8 b) public pure returns (int8 x) { + x = a - b; + } +} +// ---- +// f(int256,int256): 5, 6 -> -1 +// f(int256,int256): -2, 1 -> -3 +// f(int256,int256): -2, 2 -> -4 +// f(int256,int256): 2, -2 -> 4 +// f(int256,int256): 2, 2 -> 0 +// f(int256,int256): -5, -6 -> 1 +// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000 +// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): 5, 6 -> -1 +// g(int8,int8): -2, 1 -> -3 +// g(int8,int8): -2, 2 -> -4 +// g(int8,int8): 2, -2 -> 4 +// g(int8,int8): 2, 2 -> 0 +// g(int8,int8): -5, -6 -> 1 +// g(int8,int8): 126, -1 -> 127 +// g(int8,int8): 1, -126 -> 127 +// g(int8,int8): 127, -1 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): 1, -127 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -127, 1 -> -128 +// g(int8,int8): -1, 127 -> -128 +// g(int8,int8): -127, 2 -> FAILURE, hex"4e487b71", 0x11 +// g(int8,int8): -2, 127 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed_standard_input.json b/examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed_standard_input.json new file mode 100644 index 00000000..7016c08d --- /dev/null +++ b/examples/test/semanticTests/viaYul_detect_sub_overflow_signed/detect_sub_overflow_signed_standard_input.json @@ -0,0 +1,175 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct.sol b/examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct.sol new file mode 100644 index 00000000..66a92469 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct.sol @@ -0,0 +1,18 @@ +pragma abicoder v2; +contract C { + struct S { + uint16[] m; + } + function f(S calldata s) public pure returns (bool correct) { + int8 x = int8(int16(s.m[0])); + uint r; + assembly { + r := x + } + correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80; + } +} +// ==== +// compileViaYul: true +// ---- +// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true diff --git a/examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct_standard_input.json b/examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct_standard_input.json new file mode 100644 index 00000000..c8520db1 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_calldata_struct/dirty_calldata_struct_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array.sol b/examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array.sol new file mode 100644 index 00000000..36a253b0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array.sol @@ -0,0 +1,18 @@ +contract C { + function f() public pure returns (bool correct) { + uint8[] memory m = new uint8[](1); + assembly { + mstore(add(m, 32), 258) + } + uint8 x = m[0]; + uint r; + assembly { + r := x + } + correct = (m[0] == 0x02) && (r == 0x02); + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array_standard_input.json b/examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array_standard_input.json new file mode 100644 index 00000000..49a4bd61 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_dynamic_array/dirty_memory_dynamic_array_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32.sol b/examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32.sol new file mode 100644 index 00000000..fc2fe425 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32.sol @@ -0,0 +1,18 @@ +contract C { + function f() public pure returns (bool correct) { + uint256[1] memory m; + assembly { + mstore(m, 0xdeadbeef15dead) + } + int32 x = int32(uint32(m[0])); + uint r; + assembly { + r := x + } + correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead)); + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32_standard_input.json b/examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32_standard_input.json new file mode 100644 index 00000000..f27b6850 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_int32/dirty_memory_int32_standard_input.json @@ -0,0 +1,199 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array.sol b/examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array.sol new file mode 100644 index 00000000..4742bae2 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array.sol @@ -0,0 +1,18 @@ +contract C { + function f() public pure returns (bool correct) { + uint8[1] memory m; + assembly { + mstore(m, 257) + } + uint8 x = m[0]; + uint r; + assembly { + r := x + } + correct = (m[0] == 0x01) && (r == 0x01); + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array_standard_input.json b/examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array_standard_input.json new file mode 100644 index 00000000..abed1a64 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_static_array/dirty_memory_static_array_standard_input.json @@ -0,0 +1,193 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct.sol b/examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct.sol new file mode 100644 index 00000000..411cbe06 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct.sol @@ -0,0 +1,22 @@ +contract C { + struct S { + uint8[] m; + } + function f() public pure returns (bool correct) { + S memory s; + s.m = new uint8[](1); + assembly { + mstore(add(s, 64), 257) + } + uint8 x = s.m[0]; + uint r; + assembly { + r := x + } + correct = r == 0x01; + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct_standard_input.json b/examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct_standard_input.json new file mode 100644 index 00000000..add7b936 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_struct/dirty_memory_struct_standard_input.json @@ -0,0 +1,97 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32.sol b/examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32.sol new file mode 100644 index 00000000..a23a566c --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32.sol @@ -0,0 +1,18 @@ +contract C { + function f() public pure returns (bool correct) { + uint256[1] memory m; + assembly { + mstore(m, 0xdeadbeef15dead) + } + uint32 x = uint32(m[0]); + uint r; + assembly { + r := x + } + correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead); + } +} +// ==== +// compileViaYul: true +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32_standard_input.json b/examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32_standard_input.json new file mode 100644 index 00000000..27c53889 --- /dev/null +++ b/examples/test/semanticTests/viaYul_dirty_memory_uint32/dirty_memory_uint32_standard_input.json @@ -0,0 +1,109 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer.sol b/examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer.sol new file mode 100644 index 00000000..ae6cff0e --- /dev/null +++ b/examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer.sol @@ -0,0 +1,7 @@ +contract C { + function f() public { + assembly{ mstore(0x40, sub(0, 1)) } + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer_standard_input.json b/examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer_standard_input.json new file mode 100644 index 00000000..5694b2b9 --- /dev/null +++ b/examples/test/semanticTests/viaYul_empty_return_corrupted_free_memory_pointer/empty_return_corrupted_free_memory_pointer_standard_input.json @@ -0,0 +1,82 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp/exp.sol b/examples/test/semanticTests/viaYul_exp/exp.sol new file mode 100644 index 00000000..324256b4 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp/exp.sol @@ -0,0 +1,17 @@ +contract C { + function f(uint x, uint y) public returns (uint) { + return x**y; + } +} +// ---- +// f(uint256,uint256): 0, 0 -> 1 +// f(uint256,uint256): 0, 1 -> 0x00 +// f(uint256,uint256): 0, 2 -> 0x00 +// f(uint256,uint256): 1, 0 -> 1 +// f(uint256,uint256): 1, 1 -> 1 +// f(uint256,uint256): 1, 2 -> 1 +// f(uint256,uint256): 2, 0 -> 1 +// f(uint256,uint256): 2, 1 -> 2 +// f(uint256,uint256): 2, 2 -> 4 +// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343 +// f(uint256,uint256): 128, 2 -> 0x4000 diff --git a/examples/test/semanticTests/viaYul_exp/exp_standard_input.json b/examples/test/semanticTests/viaYul_exp/exp_standard_input.json new file mode 100644 index 00000000..f8edb81d --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp/exp_standard_input.json @@ -0,0 +1,169 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp_literals/exp_literals.sol b/examples/test/semanticTests/viaYul_exp_literals/exp_literals.sol new file mode 100644 index 00000000..382d7518 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_literals/exp_literals.sol @@ -0,0 +1,49 @@ +contract C { + function exp_2(uint y) public returns (uint) { + return 2**y; + } + function exp_minus_2(uint y) public returns (int) { + return (-2)**y; + } + + function exp_uint_max(uint y) public returns (uint) { + return (2**256 - 1)**y; + } + function exp_int_max(uint y) public returns (int) { + return ((-2)**255)**y; + } + + function exp_5(uint y) public returns (uint) { + return 5**y; + } + function exp_minus_5(uint y) public returns (int) { + return (-5)**y; + } + + function exp_256(uint y) public returns (uint) { + return 256**y; + } + function exp_minus_256(uint y) public returns (int) { + return (-256)**y; + } + +} +// ==== +// compileViaYul: true +// ---- +// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968 +// exp_2(uint256): 256 -> FAILURE, hex"4e487b71", 0x11 +// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// exp_minus_2(uint256): 256 -> FAILURE, hex"4e487b71", 0x11 +// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935 +// exp_uint_max(uint256): 2 -> FAILURE, hex"4e487b71", 0x11 +// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// exp_int_max(uint256): 2 -> FAILURE, hex"4e487b71", 0x11 +// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625 +// exp_5(uint256): 111 -> FAILURE, hex"4e487b71", 0x11 +// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125 +// exp_minus_5(uint256): 110 -> FAILURE, hex"4e487b71", 0x11 +// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656 +// exp_256(uint256): 32 -> FAILURE, hex"4e487b71", 0x11 +// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656 +// exp_minus_256(uint256): 32 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_exp_literals/exp_literals_standard_input.json b/examples/test/semanticTests/viaYul_exp_literals/exp_literals_standard_input.json new file mode 100644 index 00000000..4def8147 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_literals/exp_literals_standard_input.json @@ -0,0 +1,166 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success.sol b/examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success.sol new file mode 100644 index 00000000..12ab3392 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success.sol @@ -0,0 +1,39 @@ +contract C { + function exp_2(uint y) public returns (uint) { + return 2**y; + } + function exp_minus_2(uint y) public returns (int) { + return (-2)**y; + } + + function exp_uint_max(uint y) public returns (uint) { + return (2**256 - 1)**y; + } + function exp_int_max(uint y) public returns (int) { + return ((-2)**255)**y; + } + + function exp_5(uint y) public returns (uint) { + return 5**y; + } + function exp_minus_5(uint y) public returns (int) { + return (-5)**y; + } + + function exp_256(uint y) public returns (uint) { + return 256**y; + } + function exp_minus_256(uint y) public returns (int) { + return (-256)**y; + } + +} +// ---- +// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968 +// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935 +// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625 +// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125 +// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656 +// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656 diff --git a/examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success_standard_input.json b/examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success_standard_input.json new file mode 100644 index 00000000..cdee18c5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_literals_success/exp_literals_success_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp_neg/exp_neg.sol b/examples/test/semanticTests/viaYul_exp_neg/exp_neg.sol new file mode 100644 index 00000000..a6ba617d --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_neg/exp_neg.sol @@ -0,0 +1,31 @@ +contract C { + function f(int x, uint y) public returns (int) { + return x**y; + } +} +// ---- +// f(int256,uint256): 0, 0 -> 1 +// f(int256,uint256): 0, 1 -> 0x00 +// f(int256,uint256): 0, 2 -> 0x00 +// f(int256,uint256): 1, 0 -> 1 +// f(int256,uint256): 1, 1 -> 1 +// f(int256,uint256): 1, 2 -> 1 +// f(int256,uint256): 2, 0 -> 1 +// f(int256,uint256): 2, 1 -> 2 +// f(int256,uint256): 2, 2 -> 4 +// f(int256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343 +// f(int256,uint256): 128, 2 -> 0x4000 +// f(int256,uint256): -1, 0 -> 1 +// f(int256,uint256): -1, 1 -> -1 +// f(int256,uint256): -1, 2 -> 1 +// f(int256,uint256): -2, 0 -> 1 +// f(int256,uint256): -2, 1 -> -2 +// f(int256,uint256): -2, 2 -> 4 +// f(int256,uint256): -7, 63 -> -174251498233690814305510551794710260107945042018748343 +// f(int256,uint256): -128, 2 -> 0x4000 +// f(int256,uint256): -1, 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> -1 +// f(int256,uint256): -2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// f(int256,uint256): -8, 85 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// f(int256,uint256): -131072, 15 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// f(int256,uint256): -32, 51 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 +// f(int256,uint256): -57896044618658097711785492504343953926634992332820282019728792003956564819968, 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968 diff --git a/examples/test/semanticTests/viaYul_exp_neg/exp_neg_standard_input.json b/examples/test/semanticTests/viaYul_exp_neg/exp_neg_standard_input.json new file mode 100644 index 00000000..6ee99ce8 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_neg/exp_neg_standard_input.json @@ -0,0 +1,223 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + }, + "define_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint x, uint y, uint z) {\n (uint c, uint b, uint a) = f();\n (x, y, z) = (a, b, c);\n }\n function h() public pure returns (uint) {\n (,,uint a) = f();\n return a;\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "struct_member_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint[] b;\n uint c;\n }\n\n S s;\n constructor() {\n s.a = 42;\n s.b.push(1);\n s.b.push(2);\n s.b.push(3);\n s.c = 21;\n }\n\n function f(S memory m) public pure returns (uint, uint[] memory, uint) {\n return (m.a, m.b, m.c);\n }\n function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]);\n }\n function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]);\n }\n function h() external view returns (uint, uint, uint, uint, uint, uint) {\n return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3\n// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3\n// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17\n// h() -> 42, 3, 21, 1, 2, 3\n" + }, + "local_tuple_assignment.sol": { + "content": "contract C {\n uint public x = 17;\n function f(uint a1, uint a2) public returns (uint r1, uint r2) {\n (uint b1, uint b2) = (a1, a2);\n (r1, x, r2) = (b1, b2, b2);\n }\n function g() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], m[2]) = (1, x, 3);\n return (m[2], m[1], m[0]);\n }\n function h() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], , m[2], m[0]) = (1, x, 3, 4, 42);\n return (m[2], m[1], m[0]);\n }\n function i() public returns (uint a, uint b, uint c, uint d) {\n (a) = 42;\n (((((b))))) = 23;\n c = (((17)));\n (((d))) = (13);\n }\n}\n// ----\n// x() -> 17\n// f(uint256,uint256): 23, 42 -> 23, 42\n// x() -> 42\n// g() -> 3, 42, 1\n// h() -> 4, 42, 1\n// i() -> 42, 23, 17, 13\n" + }, + "string_literals.sol": { + "content": "contract C {\n function short_dyn() public pure returns (string memory x) {\n x = \"abc\";\n }\n function long_dyn() public pure returns (string memory x) {\n x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n }\n function short_bytes_dyn() public pure returns (bytes memory x) {\n x = \"abc\";\n }\n function long_bytes_dyn() public pure returns (bytes memory x) {\n x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n }\n function bytesNN() public pure returns (bytes3 x) {\n x = \"abc\";\n }\n function bytesNN_padded() public pure returns (bytes4 x) {\n x = \"abc\";\n }\n}\n// ----\n// short_dyn() -> 0x20, 3, \"abc\"\n// long_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// short_bytes_dyn() -> 0x20, 3, \"abc\"\n// long_bytes_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// bytesNN() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n// bytesNN_padded() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "local_assignment.sol": { + "content": "contract C {\n function f(uint a) public pure returns (uint x) {\n uint b = a;\n x = b;\n }\n}\n// ----\n// f(uint256): 6 -> 6\n" + }, + "exp_neg.sol": { + "content": "contract C {\n function f(int x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int256,uint256): 0, 0 -> 1\n// f(int256,uint256): 0, 1 -> 0x00\n// f(int256,uint256): 0, 2 -> 0x00\n// f(int256,uint256): 1, 0 -> 1\n// f(int256,uint256): 1, 1 -> 1\n// f(int256,uint256): 1, 2 -> 1\n// f(int256,uint256): 2, 0 -> 1\n// f(int256,uint256): 2, 1 -> 2\n// f(int256,uint256): 2, 2 -> 4\n// f(int256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(int256,uint256): 128, 2 -> 0x4000\n// f(int256,uint256): -1, 0 -> 1\n// f(int256,uint256): -1, 1 -> -1\n// f(int256,uint256): -1, 2 -> 1\n// f(int256,uint256): -2, 0 -> 1\n// f(int256,uint256): -2, 1 -> -2\n// f(int256,uint256): -2, 2 -> 4\n// f(int256,uint256): -7, 63 -> -174251498233690814305510551794710260107945042018748343\n// f(int256,uint256): -128, 2 -> 0x4000\n// f(int256,uint256): -1, 115792089237316195423570985008687907853269984665640564039457584007913129639935 -> -1\n// f(int256,uint256): -2, 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -8, 85 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -131072, 15 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -32, 51 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// f(int256,uint256): -57896044618658097711785492504343953926634992332820282019728792003956564819968, 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow.sol b/examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow.sol new file mode 100644 index 00000000..a966e3cc --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow.sol @@ -0,0 +1,36 @@ +contract C { + function f(int8 x, uint y) public returns (int) { + return x**y; + } + function g(int256 x, uint y) public returns (int) { + return x**y; + } +} +// ---- +// f(int8,uint256): 2, 6 -> 64 +// f(int8,uint256): 2, 7 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): 2, 8 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -2, 6 -> 64 +// f(int8,uint256): -2, 7 -> -128 +// f(int8,uint256): -2, 8 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): 6, 3 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): 7, 2 -> 0x31 +// f(int8,uint256): 7, 3 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -7, 2 -> 0x31 +// f(int8,uint256): -7, 3 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -7, 4 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): 127, 31 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): 127, 131 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -128, 0 -> 1 +// f(int8,uint256): -128, 1 -> -128 +// f(int8,uint256): -128, 31 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -128, 131 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -11, 2 -> 121 +// f(int8,uint256): -12, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): 12, 2 -> FAILURE, hex"4e487b71", 0x11 +// f(int8,uint256): -5, 3 -> -125 +// f(int8,uint256): -6, 3 -> FAILURE, hex"4e487b71", 0x11 +// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249 +// g(int256,uint256): -7, 91 -> FAILURE, hex"4e487b71", 0x11 +// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369 +// g(int256,uint256): -63, 43 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow_standard_input.json b/examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow_standard_input.json new file mode 100644 index 00000000..588a2332 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_neg_overflow/exp_neg_overflow_standard_input.json @@ -0,0 +1,184 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp_overflow/exp_overflow.sol b/examples/test/semanticTests/viaYul_exp_overflow/exp_overflow.sol new file mode 100644 index 00000000..7a100c2b --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_overflow/exp_overflow.sol @@ -0,0 +1,29 @@ +contract C { + function f(uint8 x, uint8 y) public returns (uint) { + return x**y; + } + function g(uint x, uint y) public returns (uint) { + return x**y; + } +} +// ---- +// f(uint8,uint8): 2, 7 -> 0x80 +// f(uint8,uint8): 2, 8 -> FAILURE, hex"4e487b71", 0x11 +// f(uint8,uint8): 15, 2 -> 225 +// f(uint8,uint8): 6, 3 -> 0xd8 +// f(uint8,uint8): 7, 2 -> 0x31 +// f(uint8,uint8): 7, 3 -> FAILURE, hex"4e487b71", 0x11 +// f(uint8,uint8): 7, 4 -> FAILURE, hex"4e487b71", 0x11 +// f(uint8,uint8): 255, 31 -> FAILURE, hex"4e487b71", 0x11 +// f(uint8,uint8): 255, 131 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000 +// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375 +// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311 +// g(uint256,uint256): 255, 33 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 255, 131 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792 +// g(uint256,uint256): 258, 37 -> FAILURE, hex"4e487b71", 0x11 +// g(uint256,uint256): 258, 131 -> FAILURE, hex"4e487b71", 0x11 diff --git a/examples/test/semanticTests/viaYul_exp_overflow/exp_overflow_standard_input.json b/examples/test/semanticTests/viaYul_exp_overflow/exp_overflow_standard_input.json new file mode 100644 index 00000000..f1a45db5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_overflow/exp_overflow_standard_input.json @@ -0,0 +1,202 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_exp_various/exp_various.sol b/examples/test/semanticTests/viaYul_exp_various/exp_various.sol new file mode 100644 index 00000000..3e9cf9d4 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_various/exp_various.sol @@ -0,0 +1,48 @@ +contract C { + function f(uint8 x, uint8 y) public returns (uint) { + return x**y; + } + function g(uint x, uint y) public returns (uint) { + return x**y; + } +} +// ---- +// f(uint8,uint8): 0, 0 -> 1 +// f(uint8,uint8): 0, 1 -> 0x00 +// f(uint8,uint8): 0, 2 -> 0x00 +// f(uint8,uint8): 0, 3 -> 0x00 +// f(uint8,uint8): 1, 0 -> 1 +// f(uint8,uint8): 1, 1 -> 1 +// f(uint8,uint8): 1, 2 -> 1 +// f(uint8,uint8): 1, 3 -> 1 +// f(uint8,uint8): 2, 0 -> 1 +// f(uint8,uint8): 2, 1 -> 2 +// f(uint8,uint8): 2, 2 -> 4 +// f(uint8,uint8): 2, 3 -> 8 +// f(uint8,uint8): 3, 0 -> 1 +// f(uint8,uint8): 3, 1 -> 3 +// f(uint8,uint8): 3, 2 -> 9 +// f(uint8,uint8): 3, 3 -> 0x1b +// f(uint8,uint8): 10, 0 -> 1 +// f(uint8,uint8): 10, 1 -> 0x0a +// f(uint8,uint8): 10, 2 -> 100 +// g(uint256,uint256): 0, 0 -> 1 +// g(uint256,uint256): 0, 1 -> 0x00 +// g(uint256,uint256): 0, 2 -> 0x00 +// g(uint256,uint256): 0, 3 -> 0x00 +// g(uint256,uint256): 1, 0 -> 1 +// g(uint256,uint256): 1, 1 -> 1 +// g(uint256,uint256): 1, 2 -> 1 +// g(uint256,uint256): 1, 3 -> 1 +// g(uint256,uint256): 2, 0 -> 1 +// g(uint256,uint256): 2, 1 -> 2 +// g(uint256,uint256): 2, 2 -> 4 +// g(uint256,uint256): 2, 3 -> 8 +// g(uint256,uint256): 3, 0 -> 1 +// g(uint256,uint256): 3, 1 -> 3 +// g(uint256,uint256): 3, 2 -> 9 +// g(uint256,uint256): 3, 3 -> 0x1b +// g(uint256,uint256): 10, 10 -> 10000000000 +// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936 +// g(uint256,uint256): 256, 2 -> 0x010000 +// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/viaYul_exp_various/exp_various_standard_input.json b/examples/test/semanticTests/viaYul_exp_various/exp_various_standard_input.json new file mode 100644 index 00000000..80317376 --- /dev/null +++ b/examples/test/semanticTests/viaYul_exp_various/exp_various_standard_input.json @@ -0,0 +1,118 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_function_address/function_address.sol b/examples/test/semanticTests/viaYul_function_address/function_address.sol new file mode 100644 index 00000000..0c1c58dd --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_address/function_address.sol @@ -0,0 +1,15 @@ +contract C { + function f() external returns (address) { + return this.f.address; + } + function g() external returns (bool) { + return this.f.address == address(this); + } + function h(function() external a) public returns (address) { + return a.address; + } +} +// ---- +// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e +// g() -> true +// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF diff --git a/examples/test/semanticTests/viaYul_function_address/function_address_standard_input.json b/examples/test/semanticTests/viaYul_function_address/function_address_standard_input.json new file mode 100644 index 00000000..1ba0831f --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_address/function_address_standard_input.json @@ -0,0 +1,145 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks.sol b/examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks.sol new file mode 100644 index 00000000..6f5f9082 --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks.sol @@ -0,0 +1,28 @@ +contract C { + function f() public returns (uint) { + } + function g(uint x, uint y) public returns (uint) { + } + function h() public payable returns (uint) { + } + function i(bytes32 b) public returns (bytes32) { + } + function j(bool b) public returns (bool) { + } + function k(bytes32 b) public returns (bytes32) { + } + function s() public returns (uint256[] memory) { + } + function t(uint) public pure { + } +} +// ---- +// f() -> 0 +// g(uint256,uint256): 1, -2 -> 0 +// h(), 1 ether -> 0 +// i(bytes32), 1 ether: 2 -> FAILURE +// i(bytes32): 2 -> 0 +// j(bool): true -> false +// k(bytes32): 0x31 -> 0x00 +// s(): hex"4200ef" -> 0x20, 0 +// t(uint256) -> FAILURE diff --git a/examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks_standard_input.json b/examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks_standard_input.json new file mode 100644 index 00000000..0702d4de --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_entry_checks/function_entry_checks_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_function_pointers/function_pointers.sol b/examples/test/semanticTests/viaYul_function_pointers/function_pointers.sol new file mode 100644 index 00000000..b34f0198 --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_pointers/function_pointers.sol @@ -0,0 +1,23 @@ +contract C { + function f() public { + function() internal returns (uint) _f; + _f(); + } + function g() public { + function() external returns (uint) _g; + _g(); + } + function h1() internal returns (function() internal returns (uint) _h) {} + function h2() public { + h1()(); + } + function k1() internal returns (function() external returns (uint) _k) {} + function k2() public { + k1()(); + } +} +// ---- +// f() -> FAILURE, hex"4e487b71", 0x51 +// g() -> FAILURE +// h2() -> FAILURE, hex"4e487b71", 0x51 +// k2() -> FAILURE diff --git a/examples/test/semanticTests/viaYul_function_pointers/function_pointers_standard_input.json b/examples/test/semanticTests/viaYul_function_pointers/function_pointers_standard_input.json new file mode 100644 index 00000000..3542727f --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_pointers/function_pointers_standard_input.json @@ -0,0 +1,103 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_function_selector/function_selector.sol b/examples/test/semanticTests/viaYul_function_selector/function_selector.sol new file mode 100644 index 00000000..4737a36d --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_selector/function_selector.sol @@ -0,0 +1,11 @@ +contract C { + function f() external returns (bytes4) { + return this.f.selector; + } + function h(function() external a) public returns (bytes4) { + return a.selector; + } +} +// ---- +// f() -> left(0x26121ff0) +// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242) diff --git a/examples/test/semanticTests/viaYul_function_selector/function_selector_standard_input.json b/examples/test/semanticTests/viaYul_function_selector/function_selector_standard_input.json new file mode 100644 index 00000000..159e895b --- /dev/null +++ b/examples/test/semanticTests/viaYul_function_selector/function_selector_standard_input.json @@ -0,0 +1,130 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_if/if.sol b/examples/test/semanticTests/viaYul_if/if.sol new file mode 100644 index 00000000..0fe752d5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_if/if.sol @@ -0,0 +1,80 @@ +contract C { + function f(bool condition) public returns (uint x) { + x = 23; + if (condition) + x = 42; + } + function g(bool condition) public returns (uint x) { + x = 0; + if (condition) + x = 42; + else + x = 23; + } + function h(bool condition) public returns (uint x) { + if (condition) + return 42; + x = 23; + } + function i(bool condition) public returns (uint x) { + if (condition) + x = 10; + else + return 23; + x = 42; + } + function j(uint a, uint b) public returns (uint x, uint y) { + x = 42; + if (a + b < 10) + x = a; + else + x = b; + y = 100; + } + function k(uint a, uint b) public returns (uint x, uint y) { + x = 42; + do { + if (a + b < 10) + { + if (a == b) + { + x = 99; y = 99; + break; + } + else + { + x = a; + } + } + else + { + x = b; + if (a != b) + y = 17; + else + y = 13; + break; + } + y = 100; + } while(false); + } +} +// ---- +// f(bool): 0 -> 23 +// f(bool): 1 -> 42 +// g(bool): 0 -> 23 +// g(bool): 1 -> 42 +// h(bool): 0 -> 23 +// h(bool): 1 -> 42 +// i(bool): 0 -> 23 +// i(bool): 1 -> 42 +// j(uint256,uint256): 1, 3 -> 1, 100 +// j(uint256,uint256): 3, 1 -> 3, 100 +// j(uint256,uint256): 10, 23 -> 23, 100 +// j(uint256,uint256): 23, 10 -> 10, 100 +// k(uint256,uint256): 1, 3 -> 1, 100 +// k(uint256,uint256): 3, 1 -> 3, 100 +// k(uint256,uint256): 3, 3 -> 99, 99 +// k(uint256,uint256): 10, 23 -> 23, 17 +// k(uint256,uint256): 23, 10 -> 10, 17 +// k(uint256,uint256): 23, 23 -> 23, 13 diff --git a/examples/test/semanticTests/viaYul_if/if_standard_input.json b/examples/test/semanticTests/viaYul_if/if_standard_input.json new file mode 100644 index 00000000..833973e3 --- /dev/null +++ b/examples/test/semanticTests/viaYul_if/if_standard_input.json @@ -0,0 +1,151 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_keccak/keccak.sol b/examples/test/semanticTests/viaYul_keccak/keccak.sol new file mode 100644 index 00000000..017d67c5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_keccak/keccak.sol @@ -0,0 +1,12 @@ +contract C { + function keccak1() public pure returns (bytes32) { + return keccak256("123"); + } + function keccak2() public pure returns (bytes32) { + bytes memory a = "123"; + return keccak256(a); + } +} +// ---- +// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107 +// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107 diff --git a/examples/test/semanticTests/viaYul_keccak/keccak_standard_input.json b/examples/test/semanticTests/viaYul_keccak/keccak_standard_input.json new file mode 100644 index 00000000..72284027 --- /dev/null +++ b/examples/test/semanticTests/viaYul_keccak/keccak_standard_input.json @@ -0,0 +1,67 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment.sol b/examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment.sol new file mode 100644 index 00000000..529513ea --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f(address a) public pure returns (address x) { + address b = a; + x = b; + } +} +// ---- +// f(address): 0x1234 -> 0x1234 diff --git a/examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment_standard_input.json b/examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment_standard_input.json new file mode 100644 index 00000000..420a9f62 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_address_assignment/local_address_assignment_standard_input.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_local_assignment/local_assignment.sol b/examples/test/semanticTests/viaYul_local_assignment/local_assignment.sol new file mode 100644 index 00000000..f77d25c6 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_assignment/local_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint a) public pure returns (uint x) { + uint b = a; + x = b; + } +} +// ---- +// f(uint256): 6 -> 6 diff --git a/examples/test/semanticTests/viaYul_local_assignment/local_assignment_standard_input.json b/examples/test/semanticTests/viaYul_local_assignment/local_assignment_standard_input.json new file mode 100644 index 00000000..4f147448 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_assignment/local_assignment_standard_input.json @@ -0,0 +1,220 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + }, + "define_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint x, uint y, uint z) {\n (uint c, uint b, uint a) = f();\n (x, y, z) = (a, b, c);\n }\n function h() public pure returns (uint) {\n (,,uint a) = f();\n return a;\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "struct_member_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint[] b;\n uint c;\n }\n\n S s;\n constructor() {\n s.a = 42;\n s.b.push(1);\n s.b.push(2);\n s.b.push(3);\n s.c = 21;\n }\n\n function f(S memory m) public pure returns (uint, uint[] memory, uint) {\n return (m.a, m.b, m.c);\n }\n function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]);\n }\n function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]);\n }\n function h() external view returns (uint, uint, uint, uint, uint, uint) {\n return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3\n// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3\n// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17\n// h() -> 42, 3, 21, 1, 2, 3\n" + }, + "local_tuple_assignment.sol": { + "content": "contract C {\n uint public x = 17;\n function f(uint a1, uint a2) public returns (uint r1, uint r2) {\n (uint b1, uint b2) = (a1, a2);\n (r1, x, r2) = (b1, b2, b2);\n }\n function g() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], m[2]) = (1, x, 3);\n return (m[2], m[1], m[0]);\n }\n function h() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], , m[2], m[0]) = (1, x, 3, 4, 42);\n return (m[2], m[1], m[0]);\n }\n function i() public returns (uint a, uint b, uint c, uint d) {\n (a) = 42;\n (((((b))))) = 23;\n c = (((17)));\n (((d))) = (13);\n }\n}\n// ----\n// x() -> 17\n// f(uint256,uint256): 23, 42 -> 23, 42\n// x() -> 42\n// g() -> 3, 42, 1\n// h() -> 4, 42, 1\n// i() -> 42, 23, 17, 13\n" + }, + "string_literals.sol": { + "content": "contract C {\n function short_dyn() public pure returns (string memory x) {\n x = \"abc\";\n }\n function long_dyn() public pure returns (string memory x) {\n x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n }\n function short_bytes_dyn() public pure returns (bytes memory x) {\n x = \"abc\";\n }\n function long_bytes_dyn() public pure returns (bytes memory x) {\n x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n }\n function bytesNN() public pure returns (bytes3 x) {\n x = \"abc\";\n }\n function bytesNN_padded() public pure returns (bytes4 x) {\n x = \"abc\";\n }\n}\n// ----\n// short_dyn() -> 0x20, 3, \"abc\"\n// long_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// short_bytes_dyn() -> 0x20, 3, \"abc\"\n// long_bytes_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// bytesNN() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n// bytesNN_padded() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n" + }, + "local_assignment.sol": { + "content": "contract C {\n function f(uint a) public pure returns (uint x) {\n uint b = a;\n x = b;\n }\n}\n// ----\n// f(uint256): 6 -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment.sol b/examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment.sol new file mode 100644 index 00000000..d32e281d --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f(bool a) public pure returns (bool x) { + bool b = a; + x = b; + } +} +// ---- +// f(bool): true -> true diff --git a/examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment_standard_input.json b/examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment_standard_input.json new file mode 100644 index 00000000..75baabe6 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_bool_assignment/local_bool_assignment_standard_input.json @@ -0,0 +1,148 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment.sol b/examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment.sol new file mode 100644 index 00000000..ff7f0785 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment.sol @@ -0,0 +1,30 @@ +contract C { + uint public x = 17; + function f(uint a1, uint a2) public returns (uint r1, uint r2) { + (uint b1, uint b2) = (a1, a2); + (r1, x, r2) = (b1, b2, b2); + } + function g() public returns (uint a, uint b, uint c) { + uint256[3] memory m; + (m[0], m[1], m[2]) = (1, x, 3); + return (m[2], m[1], m[0]); + } + function h() public returns (uint a, uint b, uint c) { + uint256[3] memory m; + (m[0], m[1], , m[2], m[0]) = (1, x, 3, 4, 42); + return (m[2], m[1], m[0]); + } + function i() public returns (uint a, uint b, uint c, uint d) { + (a) = 42; + (((((b))))) = 23; + c = (((17))); + (((d))) = (13); + } +} +// ---- +// x() -> 17 +// f(uint256,uint256): 23, 42 -> 23, 42 +// x() -> 42 +// g() -> 3, 42, 1 +// h() -> 4, 42, 1 +// i() -> 42, 23, 17, 13 diff --git a/examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment_standard_input.json b/examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment_standard_input.json new file mode 100644 index 00000000..94dce2c7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_tuple_assignment/local_tuple_assignment_standard_input.json @@ -0,0 +1,214 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + }, + "define_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint x, uint y, uint z) {\n (uint c, uint b, uint a) = f();\n (x, y, z) = (a, b, c);\n }\n function h() public pure returns (uint) {\n (,,uint a) = f();\n return a;\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "struct_member_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint[] b;\n uint c;\n }\n\n S s;\n constructor() {\n s.a = 42;\n s.b.push(1);\n s.b.push(2);\n s.b.push(3);\n s.c = 21;\n }\n\n function f(S memory m) public pure returns (uint, uint[] memory, uint) {\n return (m.a, m.b, m.c);\n }\n function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]);\n }\n function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]);\n }\n function h() external view returns (uint, uint, uint, uint, uint, uint) {\n return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3\n// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3\n// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17\n// h() -> 42, 3, 21, 1, 2, 3\n" + }, + "local_tuple_assignment.sol": { + "content": "contract C {\n uint public x = 17;\n function f(uint a1, uint a2) public returns (uint r1, uint r2) {\n (uint b1, uint b2) = (a1, a2);\n (r1, x, r2) = (b1, b2, b2);\n }\n function g() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], m[2]) = (1, x, 3);\n return (m[2], m[1], m[0]);\n }\n function h() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], , m[2], m[0]) = (1, x, 3, 4, 42);\n return (m[2], m[1], m[0]);\n }\n function i() public returns (uint a, uint b, uint c, uint d) {\n (a) = 42;\n (((((b))))) = 23;\n c = (((17)));\n (((d))) = (13);\n }\n}\n// ----\n// x() -> 17\n// f(uint256,uint256): 23, 42 -> 23, 42\n// x() -> 42\n// g() -> 3, 42, 1\n// h() -> 4, 42, 1\n// i() -> 42, 23, 17, 13\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init.sol b/examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init.sol new file mode 100644 index 00000000..f1b2b174 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure returns (uint) { + uint x; + return x; + } +} +// ---- +// f() -> 0 diff --git a/examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init_standard_input.json b/examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init_standard_input.json new file mode 100644 index 00000000..d9679693 --- /dev/null +++ b/examples/test/semanticTests/viaYul_local_variable_without_init/local_variable_without_init_standard_input.json @@ -0,0 +1,178 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_loops_break/break.sol b/examples/test/semanticTests/viaYul_loops_break/break.sol new file mode 100644 index 00000000..77ecface --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_break/break.sol @@ -0,0 +1,29 @@ +contract C { + function f() public returns (uint x) { + x = 1; + for (uint a = 0; a < 10; a = a + 1) { + x = x + x; + break; + } + } + function g() public returns (uint x) { + x = 1; + uint a = 0; + while (a < 10) { + x = x + x; + break; + a = a + 1; + } + } + function h() public returns (uint x) { + x = 1; + do { + x = x + 1; + break; + } while (x < 3); + } +} +// ---- +// f() -> 2 +// g() -> 2 +// h() -> 2 diff --git a/examples/test/semanticTests/viaYul_loops_break/break_standard_input.json b/examples/test/semanticTests/viaYul_loops_break/break_standard_input.json new file mode 100644 index 00000000..03fcfc58 --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_break/break_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "continue.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a = 0;\n for (; a < 10; a = a + 1) {\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n a = a + 1;\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n uint a = 0;\n do {\n a = a + 1;\n continue;\n x = x + x;\n } while (a < 4);\n x = x + a;\n }\n}\n// ----\n// f() -> 11\n// g() -> 11\n// h() -> 5\n" + }, + "return.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a;\n for (; a < 10; a = a + 1) {\n return x;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a;\n while (a < 10) {\n return x;\n x = x + x;\n a = a + 1;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n return x;\n } while (x < 3);\n }\n}\n// ----\n// f() -> 1\n// g() -> 1\n// h() -> 2\n" + }, + "simple.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n for (uint a = 0; a < 10; a = a + 1) {\n x = x + x;\n }\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n x = x + x;\n a = a + 1;\n }\n }\n function h() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n } while (false);\n }\n function i() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n } while (x < 3);\n }\n function j() public {\n for (;;) {break;}\n }\n}\n// ----\n// f() -> 1024\n// g() -> 1024\n// h() -> 2\n// i() -> 3\n// j() ->\n" + }, + "break.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n for (uint a = 0; a < 10; a = a + 1) {\n x = x + x;\n break;\n }\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n x = x + x;\n break;\n a = a + 1;\n }\n }\n function h() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n break;\n } while (x < 3);\n }\n}\n// ----\n// f() -> 2\n// g() -> 2\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_loops_continue/continue.sol b/examples/test/semanticTests/viaYul_loops_continue/continue.sol new file mode 100644 index 00000000..b9c3f167 --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_continue/continue.sol @@ -0,0 +1,35 @@ +contract C { + function f() public returns (uint x) { + x = 1; + uint a = 0; + for (; a < 10; a = a + 1) { + continue; + x = x + x; + } + x = x + a; + } + function g() public returns (uint x) { + x = 1; + uint a = 0; + while (a < 10) { + a = a + 1; + continue; + x = x + x; + } + x = x + a; + } + function h() public returns (uint x) { + x = 1; + uint a = 0; + do { + a = a + 1; + continue; + x = x + x; + } while (a < 4); + x = x + a; + } +} +// ---- +// f() -> 11 +// g() -> 11 +// h() -> 5 diff --git a/examples/test/semanticTests/viaYul_loops_continue/continue_standard_input.json b/examples/test/semanticTests/viaYul_loops_continue/continue_standard_input.json new file mode 100644 index 00000000..c409d2e3 --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_continue/continue_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "continue.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a = 0;\n for (; a < 10; a = a + 1) {\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n a = a + 1;\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n uint a = 0;\n do {\n a = a + 1;\n continue;\n x = x + x;\n } while (a < 4);\n x = x + a;\n }\n}\n// ----\n// f() -> 11\n// g() -> 11\n// h() -> 5\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_loops_return/return.sol b/examples/test/semanticTests/viaYul_loops_return/return.sol new file mode 100644 index 00000000..ee7062e7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_return/return.sol @@ -0,0 +1,32 @@ +contract C { + function f() public returns (uint x) { + x = 1; + uint a; + for (; a < 10; a = a + 1) { + return x; + x = x + x; + } + x = x + a; + } + function g() public returns (uint x) { + x = 1; + uint a; + while (a < 10) { + return x; + x = x + x; + a = a + 1; + } + x = x + a; + } + function h() public returns (uint x) { + x = 1; + do { + x = x + 1; + return x; + } while (x < 3); + } +} +// ---- +// f() -> 1 +// g() -> 1 +// h() -> 2 diff --git a/examples/test/semanticTests/viaYul_loops_return/return_standard_input.json b/examples/test/semanticTests/viaYul_loops_return/return_standard_input.json new file mode 100644 index 00000000..29d67dea --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_return/return_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "continue.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a = 0;\n for (; a < 10; a = a + 1) {\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n a = a + 1;\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n uint a = 0;\n do {\n a = a + 1;\n continue;\n x = x + x;\n } while (a < 4);\n x = x + a;\n }\n}\n// ----\n// f() -> 11\n// g() -> 11\n// h() -> 5\n" + }, + "return.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a;\n for (; a < 10; a = a + 1) {\n return x;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a;\n while (a < 10) {\n return x;\n x = x + x;\n a = a + 1;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n return x;\n } while (x < 3);\n }\n}\n// ----\n// f() -> 1\n// g() -> 1\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_loops_simple/simple.sol b/examples/test/semanticTests/viaYul_loops_simple/simple.sol new file mode 100644 index 00000000..a4d07632 --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_simple/simple.sol @@ -0,0 +1,37 @@ +contract C { + function f() public returns (uint x) { + x = 1; + for (uint a = 0; a < 10; a = a + 1) { + x = x + x; + } + } + function g() public returns (uint x) { + x = 1; + uint a = 0; + while (a < 10) { + x = x + x; + a = a + 1; + } + } + function h() public returns (uint x) { + x = 1; + do { + x = x + 1; + } while (false); + } + function i() public returns (uint x) { + x = 1; + do { + x = x + 1; + } while (x < 3); + } + function j() public { + for (;;) {break;} + } +} +// ---- +// f() -> 1024 +// g() -> 1024 +// h() -> 2 +// i() -> 3 +// j() -> diff --git a/examples/test/semanticTests/viaYul_loops_simple/simple_standard_input.json b/examples/test/semanticTests/viaYul_loops_simple/simple_standard_input.json new file mode 100644 index 00000000..040872d5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_loops_simple/simple_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "continue.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a = 0;\n for (; a < 10; a = a + 1) {\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n a = a + 1;\n continue;\n x = x + x;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n uint a = 0;\n do {\n a = a + 1;\n continue;\n x = x + x;\n } while (a < 4);\n x = x + a;\n }\n}\n// ----\n// f() -> 11\n// g() -> 11\n// h() -> 5\n" + }, + "return.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n uint a;\n for (; a < 10; a = a + 1) {\n return x;\n x = x + x;\n }\n x = x + a;\n }\n function g() public returns (uint x) {\n x = 1;\n uint a;\n while (a < 10) {\n return x;\n x = x + x;\n a = a + 1;\n }\n x = x + a;\n }\n function h() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n return x;\n } while (x < 3);\n }\n}\n// ----\n// f() -> 1\n// g() -> 1\n// h() -> 2\n" + }, + "simple.sol": { + "content": "contract C {\n function f() public returns (uint x) {\n x = 1;\n for (uint a = 0; a < 10; a = a + 1) {\n x = x + x;\n }\n }\n function g() public returns (uint x) {\n x = 1;\n uint a = 0;\n while (a < 10) {\n x = x + x;\n a = a + 1;\n }\n }\n function h() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n } while (false);\n }\n function i() public returns (uint x) {\n x = 1;\n do {\n x = x + 1;\n } while (x < 3);\n }\n function j() public {\n for (;;) {break;}\n }\n}\n// ----\n// f() -> 1024\n// g() -> 1024\n// h() -> 2\n// i() -> 3\n// j() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter.sol b/examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter.sol new file mode 100644 index 00000000..30647427 --- /dev/null +++ b/examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter.sol @@ -0,0 +1,24 @@ +pragma abicoder v2; +contract test { + enum E { A, B, C } + mapping(E => uint8) public table; + function set(E k, uint8 v) public { + table[k] = v; + } +} +// ---- +// table(uint8): 0 -> 0 +// table(uint8): 0x01 -> 0 +// table(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0xa1 -> +// table(uint8): 0 -> 0 +// table(uint8): 0x01 -> 0xa1 +// table(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x00, 0xef -> +// table(uint8): 0 -> 0xef +// table(uint8): 0x01 -> 0xa1 +// table(uint8): 0xa7 -> FAILURE +// set(uint8,uint8): 0x01, 0x05 -> +// table(uint8): 0 -> 0xef +// table(uint8): 0x01 -> 0x05 +// table(uint8): 0xa7 -> FAILURE diff --git a/examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter_standard_input.json b/examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter_standard_input.json new file mode 100644 index 00000000..ae0641a7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_mapping_enum_key_getter/mapping_enum_key_getter_standard_input.json @@ -0,0 +1,163 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_mapping_getters/mapping_getters.sol b/examples/test/semanticTests/viaYul_mapping_getters/mapping_getters.sol new file mode 100644 index 00000000..a709bc16 --- /dev/null +++ b/examples/test/semanticTests/viaYul_mapping_getters/mapping_getters.sol @@ -0,0 +1,38 @@ +contract test { + mapping(uint256 => uint256) public m1; + mapping(uint256 => mapping(uint256 => uint256)) public m2; + function set(uint256 k, uint256 v) public { + m1[k] = v; + } + function set(uint256 k1, uint256 k2, uint256 v) public { + m2[k1][k2] = v; + } +} +// ---- +// m1(uint256): 0 -> 0 +// m1(uint256): 0x01 -> 0 +// m1(uint256): 0xa7 -> 0 +// set(uint256,uint256): 0x01, 0xa1 -> +// m1(uint256): 0 -> 0 +// m1(uint256): 0x01 -> 0xa1 +// m1(uint256): 0xa7 -> 0 +// set(uint256,uint256): 0x00, 0xef -> +// m1(uint256): 0 -> 0xef +// m1(uint256): 0x01 -> 0xa1 +// m1(uint256): 0xa7 -> 0 +// set(uint256,uint256): 0x01, 0x05 -> +// m1(uint256): 0 -> 0xef +// m1(uint256): 0x01 -> 0x05 +// m1(uint256): 0xa7 -> 0 +// m2(uint256,uint256): 0, 0 -> 0 +// m2(uint256,uint256): 0, 0x01 -> 0 +// m2(uint256,uint256): 0xa7, 0 -> 0 +// m2(uint256,uint256): 0xa7, 0x01 -> 0 +// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23 +// m2(uint256,uint256): 0, 0x01 -> 0 +// m2(uint256,uint256): 0xa7, 0 -> 0 +// m2(uint256,uint256): 0xa7, 0x01 -> 0x23 +// set(uint256,uint256,uint256): 0, 0x01, 0xef +// m2(uint256,uint256): 0, 0x01 -> 0xef +// m2(uint256,uint256): 0xa7, 0 -> 0 +// m2(uint256,uint256): 0xa7, 0x01 -> 0x23 diff --git a/examples/test/semanticTests/viaYul_mapping_getters/mapping_getters_standard_input.json b/examples/test/semanticTests/viaYul_mapping_getters/mapping_getters_standard_input.json new file mode 100644 index 00000000..0bcd8f60 --- /dev/null +++ b/examples/test/semanticTests/viaYul_mapping_getters/mapping_getters_standard_input.json @@ -0,0 +1,124 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key.sol b/examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key.sol new file mode 100644 index 00000000..8dcd7677 --- /dev/null +++ b/examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key.sol @@ -0,0 +1,8 @@ +contract C { + mapping (string => uint) map; + function set(string memory s) public { + map[s]; + } +} +// ---- +// set(string): 0x20, 32, "01234567890123456789012345678901" -> diff --git a/examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key_standard_input.json b/examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key_standard_input.json new file mode 100644 index 00000000..74055893 --- /dev/null +++ b/examples/test/semanticTests/viaYul_mapping_string_key/mapping_string_key_standard_input.json @@ -0,0 +1,85 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow.sol b/examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow.sol new file mode 100644 index 00000000..9f87c7b9 --- /dev/null +++ b/examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow.sol @@ -0,0 +1,19 @@ +contract C { + struct S { + uint256 a; + uint256 b; + } + + function f() public pure returns (uint256 a, uint256 b){ + assembly { + // Make free memory dirty to check that the struct allocation cleans it up again. + let freeMem := mload(0x40) + mstore(freeMem, 42) + mstore(add(freeMem, 32), 42) + } + S memory s; + return (s.a, s.b); + } +} +// ---- +// f() -> 0, 0 diff --git a/examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow_standard_input.json b/examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow_standard_input.json new file mode 100644 index 00000000..56282537 --- /dev/null +++ b/examples/test/semanticTests/viaYul_memory_struct_allow/memory_struct_allow_standard_input.json @@ -0,0 +1,73 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_msg_sender/msg_sender.sol b/examples/test/semanticTests/viaYul_msg_sender/msg_sender.sol new file mode 100644 index 00000000..058f142f --- /dev/null +++ b/examples/test/semanticTests/viaYul_msg_sender/msg_sender.sol @@ -0,0 +1,9 @@ +contract C { + function test() public view returns (bool) { + address x; + assembly { x := caller() } + return x == msg.sender; + } +} +// ---- +// test() -> true diff --git a/examples/test/semanticTests/viaYul_msg_sender/msg_sender_standard_input.json b/examples/test/semanticTests/viaYul_msg_sender/msg_sender_standard_input.json new file mode 100644 index 00000000..72044de7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_msg_sender/msg_sender_standard_input.json @@ -0,0 +1,64 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_negation_bug/negation_bug.sol b/examples/test/semanticTests/viaYul_negation_bug/negation_bug.sol new file mode 100644 index 00000000..d4d1b82f --- /dev/null +++ b/examples/test/semanticTests/viaYul_negation_bug/negation_bug.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure { + -(int8(0)); + unchecked { + // Used to incorrectly use the checked unary negation function and revert. + (-(type(int8).min)); + } + } +} +// ---- +// f() -> diff --git a/examples/test/semanticTests/viaYul_negation_bug/negation_bug_standard_input.json b/examples/test/semanticTests/viaYul_negation_bug/negation_bug_standard_input.json new file mode 100644 index 00000000..619ce251 --- /dev/null +++ b/examples/test/semanticTests/viaYul_negation_bug/negation_bug_standard_input.json @@ -0,0 +1,70 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_require/require.sol b/examples/test/semanticTests/viaYul_require/require.sol new file mode 100644 index 00000000..39677b4f --- /dev/null +++ b/examples/test/semanticTests/viaYul_require/require.sol @@ -0,0 +1,43 @@ +contract C { + function f(bool a) public pure returns (bool x) { + bool b = a; + x = b; + require(b); + } + function fail() public pure returns (bool x) { + x = true; + require(false); + } + function succeed() public pure returns (bool x) { + x = true; + require(true); + } + function f2(bool a) public pure returns (bool x) { + x = a; + string memory message; + message = "fancy message!"; + require(a, message); + } + function f3(bool a) public pure returns (bool x) { + x = a; + require(a, "msg"); + } + function f4(bool a) public pure returns (bool x) { + x = a; + string memory message; + require(a, message); + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> true +// f(bool): false -> FAILURE +// fail() -> FAILURE +// succeed() -> true +// f2(bool): true -> true +// f2(bool): false -> FAILURE, hex"08c379a0", 0x20, 14, "fancy message!" +// f3(bool): true -> true +// f3(bool): false -> FAILURE, hex"08c379a0", 0x20, 3, "msg" +// f4(bool): true -> true +// f4(bool): false -> FAILURE, hex"08c379a0", 0x20, 0 diff --git a/examples/test/semanticTests/viaYul_require/require_standard_input.json b/examples/test/semanticTests/viaYul_require/require_standard_input.json new file mode 100644 index 00000000..e136703f --- /dev/null +++ b/examples/test/semanticTests/viaYul_require/require_standard_input.json @@ -0,0 +1,91 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_return/return.sol b/examples/test/semanticTests/viaYul_return/return.sol new file mode 100644 index 00000000..f58632b9 --- /dev/null +++ b/examples/test/semanticTests/viaYul_return/return.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure returns (uint x) { + return 7; + x = 3; + } +} +// ---- +// f() -> 7 diff --git a/examples/test/semanticTests/viaYul_return/return_standard_input.json b/examples/test/semanticTests/viaYul_return/return_standard_input.json new file mode 100644 index 00000000..8f5462d8 --- /dev/null +++ b/examples/test/semanticTests/viaYul_return/return_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_return_and_convert/return_and_convert.sol b/examples/test/semanticTests/viaYul_return_and_convert/return_and_convert.sol new file mode 100644 index 00000000..78e9e3be --- /dev/null +++ b/examples/test/semanticTests/viaYul_return_and_convert/return_and_convert.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (uint) { + uint8 b; + assembly { b := 0xffff } + return b; + } +} +// ---- +// f() -> 255 diff --git a/examples/test/semanticTests/viaYul_return_and_convert/return_and_convert_standard_input.json b/examples/test/semanticTests/viaYul_return_and_convert/return_and_convert_standard_input.json new file mode 100644 index 00000000..b75f13a7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_return_and_convert/return_and_convert_standard_input.json @@ -0,0 +1,181 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers.sol b/examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers.sol new file mode 100644 index 00000000..93605812 --- /dev/null +++ b/examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers.sol @@ -0,0 +1,14 @@ +contract C { + uint[] arr1; + uint[][] arr2; + function f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) { + ptr1 = arr1; + ptr2 = arr2; + } + function g() public returns (uint, uint) { + return (arr1.length, arr2.length); + } + +} +// ---- +// g() -> 0, 0 diff --git a/examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers_standard_input.json b/examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers_standard_input.json new file mode 100644 index 00000000..b73c0276 --- /dev/null +++ b/examples/test/semanticTests/viaYul_return_storage_pointers/return_storage_pointers_standard_input.json @@ -0,0 +1,196 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_short_circuit/short_circuit.sol b/examples/test/semanticTests/viaYul_short_circuit/short_circuit.sol new file mode 100644 index 00000000..b160bbd7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_short_circuit/short_circuit.sol @@ -0,0 +1,15 @@ +contract C { + function or(uint x) public returns (bool t, uint y) { + t = (x == 0 || ((x = 8) > 0)); + y = x; + } + function and(uint x) public returns (bool t, uint y) { + t = (x == 0 && ((x = 8) > 0)); + y = x; + } +} +// ---- +// or(uint256): 0 -> true, 0 +// and(uint256): 0 -> true, 8 +// or(uint256): 1 -> true, 8 +// and(uint256): 1 -> false, 1 diff --git a/examples/test/semanticTests/viaYul_short_circuit/short_circuit_standard_input.json b/examples/test/semanticTests/viaYul_short_circuit/short_circuit_standard_input.json new file mode 100644 index 00000000..1288de6d --- /dev/null +++ b/examples/test/semanticTests/viaYul_short_circuit/short_circuit_standard_input.json @@ -0,0 +1,154 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_simple_assignment/simple_assignment.sol b/examples/test/semanticTests/viaYul_simple_assignment/simple_assignment.sol new file mode 100644 index 00000000..ed0ba287 --- /dev/null +++ b/examples/test/semanticTests/viaYul_simple_assignment/simple_assignment.sol @@ -0,0 +1,8 @@ +contract C { + function f(uint a, uint b) public pure returns (uint x, uint y) { + x = a; + y = b; + } +} +// ---- +// f(uint256,uint256): 5, 6 -> 5, 6 diff --git a/examples/test/semanticTests/viaYul_simple_assignment/simple_assignment_standard_input.json b/examples/test/semanticTests/viaYul_simple_assignment/simple_assignment_standard_input.json new file mode 100644 index 00000000..86ccc19a --- /dev/null +++ b/examples/test/semanticTests/viaYul_simple_assignment/simple_assignment_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm.sol b/examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm.sol new file mode 100644 index 00000000..8e8cd78e --- /dev/null +++ b/examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm.sol @@ -0,0 +1,15 @@ +contract C { + function f() public pure returns (uint32 x) { + uint32 a; + uint32 b; + uint32 c; + assembly { + a := 1 + b := 2 + c := 3 + } + x = a + b + c; + } +} +// ---- +// f() -> 6 diff --git a/examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm_standard_input.json b/examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm_standard_input.json new file mode 100644 index 00000000..c1355552 --- /dev/null +++ b/examples/test/semanticTests/viaYul_simple_inline_asm/simple_inline_asm_standard_input.json @@ -0,0 +1,100 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_smoke_test/smoke_test.sol b/examples/test/semanticTests/viaYul_smoke_test/smoke_test.sol new file mode 100644 index 00000000..53a11869 --- /dev/null +++ b/examples/test/semanticTests/viaYul_smoke_test/smoke_test.sol @@ -0,0 +1,6 @@ +contract C { +} +// ==== +// allowNonExistingFunctions: true +// ---- +// f() -> FAILURE diff --git a/examples/test/semanticTests/viaYul_smoke_test/smoke_test_standard_input.json b/examples/test/semanticTests/viaYul_smoke_test/smoke_test_standard_input.json new file mode 100644 index 00000000..e5265a39 --- /dev/null +++ b/examples/test/semanticTests/viaYul_smoke_test/smoke_test_standard_input.json @@ -0,0 +1,121 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes.sol b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes.sol new file mode 100644 index 00000000..d1ec20db --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes.sol @@ -0,0 +1,16 @@ +contract C { + bytes b; + function f() public returns (bool correct) { + assembly { + sstore(b.slot, or("deadbeef", 0x08)) + } + bytes1 s = b[3]; + uint r; + assembly { + r := s + } + correct = r == (0x64 << 248); + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes_standard_input.json b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes_standard_input.json new file mode 100644 index 00000000..4313c478 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes/dirty_storage_bytes_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_bytes.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, or(\"deadbeef\", 0x08))\n }\n bytes1 s = b[3];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long.sol b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long.sol new file mode 100644 index 00000000..3f822cbb --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long.sol @@ -0,0 +1,18 @@ +contract C { + bytes b; + function f() public returns (bool correct) { + assembly { + sstore(b.slot, 0x41) + mstore(0, b.slot) + sstore(keccak256(0, 0x20), "deadbeefdeadbeefdeadbeefdeadbeef") + } + bytes1 s = b[31]; + uint r; + assembly { + r := s + } + correct = r == (0x66 << 248); + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long_standard_input.json b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long_standard_input.json new file mode 100644 index 00000000..f3fc3f69 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_bytes_long/dirty_storage_bytes_long_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_bytes.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, or(\"deadbeef\", 0x08))\n }\n bytes1 s = b[3];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "simple_storage.sol": { + "content": "contract C {\n uint x;\n uint y;\n function setX(uint a) public returns (uint _x) {\n x = a;\n _x = x;\n }\n function setY(uint a) public returns (uint _y) {\n y = a;\n _y = y;\n }\n}\n// ----\n// setX(uint256): 6 -> 6\n// setY(uint256): 2 -> 2\n" + }, + "dirty_storage_bytes_long.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, 0x41)\n mstore(0, b.slot)\n sstore(keccak256(0, 0x20), \"deadbeefdeadbeefdeadbeefdeadbeef\")\n }\n bytes1 s = b[31];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x66 << 248);\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array.sol b/examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array.sol new file mode 100644 index 00000000..e5d2c702 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array.sol @@ -0,0 +1,18 @@ +contract C { + uint8[] s; + function f() public returns (bool correct) { + s.push(); + assembly { + mstore(0, s.slot) + sstore(keccak256(0, 0x20), 257) + } + uint8 x = s[0]; + uint r; + assembly { + r := x + } + correct = (s[0] == 0x01) && (r == 0x01); + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array_standard_input.json b/examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array_standard_input.json new file mode 100644 index 00000000..6551793f --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_dynamic_array/dirty_storage_dynamic_array_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array.sol b/examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array.sol new file mode 100644 index 00000000..7c035f05 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array.sol @@ -0,0 +1,16 @@ +contract C { + uint8[1] s; + function f() public returns (bool correct) { + assembly { + sstore(s.slot, 257) + } + uint8 x = s[0]; + uint r; + assembly { + r := x + } + correct = (s[0] == 0x01) && (r == 0x01); + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array_standard_input.json b/examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array_standard_input.json new file mode 100644 index 00000000..faf20924 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_static_array/dirty_storage_static_array_standard_input.json @@ -0,0 +1,55 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_bytes.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, or(\"deadbeef\", 0x08))\n }\n bytes1 s = b[3];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "simple_storage.sol": { + "content": "contract C {\n uint x;\n uint y;\n function setX(uint a) public returns (uint _x) {\n x = a;\n _x = x;\n }\n function setY(uint a) public returns (uint _y) {\n y = a;\n _y = y;\n }\n}\n// ----\n// setX(uint256): 6 -> 6\n// setY(uint256): 2 -> 2\n" + }, + "dirty_storage_bytes_long.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, 0x41)\n mstore(0, b.slot)\n sstore(keccak256(0, 0x20), \"deadbeefdeadbeefdeadbeefdeadbeef\")\n }\n bytes1 s = b[31];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x66 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n S s;\n function f() public returns (bool correct) {\n s.m.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ----\n// f() -> true\n" + }, + "mappings.sol": { + "content": "contract C {\n mapping(uint => uint) simple;\n mapping(uint16 => uint) cleanup;\n mapping(string => uint) str;\n mapping(uint => mapping(uint => uint)) twodim;\n function test_simple(uint _off) public returns (uint _a, uint _b, uint _c) {\n simple[_off + 2] = 3;\n simple[_off + 3] = 4;\n simple[type(uint256).max] = 5;\n _c = simple[type(uint256).max];\n _b = simple[3 + _off];\n _a = simple[2 + _off];\n }\n function test_cleanup() public returns (bool) {\n uint16 x;\n assembly { x := 0xffff0001 }\n cleanup[x] = 3;\n return cleanup[1] == 3;\n }\n function test_str() public returns (bool) {\n str[\"abc\"] = 3;\n string memory s = \"abc\";\n return str[s] == 3;\n }\n function test_twodim() public returns (uint a, uint b) {\n twodim[2][3] = 3;\n a = twodim[3][2];\n b = twodim[2][3];\n }\n}\n// ----\n// test_simple(uint256): 0 -> 3, 4, 5\n// test_simple(uint256): 1 -> 3, 4, 5\n// test_simple(uint256): 2 -> 3, 4, 5\n// test_cleanup() -> true\n// test_str() -> true\n// test_twodim() -> 0, 3\n" + }, + "dirty_storage_static_array.sol": { + "content": "contract C {\n uint8[1] s;\n function f() public returns (bool correct) {\n assembly {\n sstore(s.slot, 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct.sol b/examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct.sol new file mode 100644 index 00000000..adcd09c7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct.sol @@ -0,0 +1,21 @@ +contract C { + struct S { + uint8[] m; + } + S s; + function f() public returns (bool correct) { + s.m.push(); + assembly { + mstore(0, s.slot) + sstore(keccak256(0, 0x20), 257) + } + uint8 x = s.m[0]; + uint r; + assembly { + r := x + } + correct = r == 0x01; + } +} +// ---- +// f() -> true diff --git a/examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct_standard_input.json b/examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct_standard_input.json new file mode 100644 index 00000000..74ede30e --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_dirty_storage_struct/dirty_storage_struct_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_bytes.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, or(\"deadbeef\", 0x08))\n }\n bytes1 s = b[3];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "simple_storage.sol": { + "content": "contract C {\n uint x;\n uint y;\n function setX(uint a) public returns (uint _x) {\n x = a;\n _x = x;\n }\n function setY(uint a) public returns (uint _y) {\n y = a;\n _y = y;\n }\n}\n// ----\n// setX(uint256): 6 -> 6\n// setY(uint256): 2 -> 2\n" + }, + "dirty_storage_bytes_long.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, 0x41)\n mstore(0, b.slot)\n sstore(keccak256(0, 0x20), \"deadbeefdeadbeefdeadbeefdeadbeef\")\n }\n bytes1 s = b[31];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x66 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n S s;\n function f() public returns (bool correct) {\n s.m.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ----\n// f() -> true\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_mappings/mappings.sol b/examples/test/semanticTests/viaYul_storage_mappings/mappings.sol new file mode 100644 index 00000000..42b7fe80 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_mappings/mappings.sol @@ -0,0 +1,37 @@ +contract C { + mapping(uint => uint) simple; + mapping(uint16 => uint) cleanup; + mapping(string => uint) str; + mapping(uint => mapping(uint => uint)) twodim; + function test_simple(uint _off) public returns (uint _a, uint _b, uint _c) { + simple[_off + 2] = 3; + simple[_off + 3] = 4; + simple[type(uint256).max] = 5; + _c = simple[type(uint256).max]; + _b = simple[3 + _off]; + _a = simple[2 + _off]; + } + function test_cleanup() public returns (bool) { + uint16 x; + assembly { x := 0xffff0001 } + cleanup[x] = 3; + return cleanup[1] == 3; + } + function test_str() public returns (bool) { + str["abc"] = 3; + string memory s = "abc"; + return str[s] == 3; + } + function test_twodim() public returns (uint a, uint b) { + twodim[2][3] = 3; + a = twodim[3][2]; + b = twodim[2][3]; + } +} +// ---- +// test_simple(uint256): 0 -> 3, 4, 5 +// test_simple(uint256): 1 -> 3, 4, 5 +// test_simple(uint256): 2 -> 3, 4, 5 +// test_cleanup() -> true +// test_str() -> true +// test_twodim() -> 0, 3 diff --git a/examples/test/semanticTests/viaYul_storage_mappings/mappings_standard_input.json b/examples/test/semanticTests/viaYul_storage_mappings/mappings_standard_input.json new file mode 100644 index 00000000..45ca3b7f --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_mappings/mappings_standard_input.json @@ -0,0 +1,52 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_bytes.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, or(\"deadbeef\", 0x08))\n }\n bytes1 s = b[3];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "simple_storage.sol": { + "content": "contract C {\n uint x;\n uint y;\n function setX(uint a) public returns (uint _x) {\n x = a;\n _x = x;\n }\n function setY(uint a) public returns (uint _y) {\n y = a;\n _y = y;\n }\n}\n// ----\n// setX(uint256): 6 -> 6\n// setY(uint256): 2 -> 2\n" + }, + "dirty_storage_bytes_long.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, 0x41)\n mstore(0, b.slot)\n sstore(keccak256(0, 0x20), \"deadbeefdeadbeefdeadbeefdeadbeef\")\n }\n bytes1 s = b[31];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x66 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n S s;\n function f() public returns (bool correct) {\n s.m.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ----\n// f() -> true\n" + }, + "mappings.sol": { + "content": "contract C {\n mapping(uint => uint) simple;\n mapping(uint16 => uint) cleanup;\n mapping(string => uint) str;\n mapping(uint => mapping(uint => uint)) twodim;\n function test_simple(uint _off) public returns (uint _a, uint _b, uint _c) {\n simple[_off + 2] = 3;\n simple[_off + 3] = 4;\n simple[type(uint256).max] = 5;\n _c = simple[type(uint256).max];\n _b = simple[3 + _off];\n _a = simple[2 + _off];\n }\n function test_cleanup() public returns (bool) {\n uint16 x;\n assembly { x := 0xffff0001 }\n cleanup[x] = 3;\n return cleanup[1] == 3;\n }\n function test_str() public returns (bool) {\n str[\"abc\"] = 3;\n string memory s = \"abc\";\n return str[s] == 3;\n }\n function test_twodim() public returns (uint a, uint b) {\n twodim[2][3] = 3;\n a = twodim[3][2];\n b = twodim[2][3];\n }\n}\n// ----\n// test_simple(uint256): 0 -> 3, 4, 5\n// test_simple(uint256): 1 -> 3, 4, 5\n// test_simple(uint256): 2 -> 3, 4, 5\n// test_cleanup() -> true\n// test_str() -> true\n// test_twodim() -> 0, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage.sol b/examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage.sol new file mode 100644 index 00000000..5253a6a1 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage.sol @@ -0,0 +1,14 @@ +contract C { + uint16 x; + bytes1 y; + uint16 z; + function f(uint8 a) public returns (uint _x) { + x = a; + y = bytes1(uint8(x) + 1); + z = uint8(y) + 1; + x = z + 1; + _x = x; + } +} +// ---- +// f(uint8): 6 -> 9 diff --git a/examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage_standard_input.json b/examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage_standard_input.json new file mode 100644 index 00000000..c4f9f4e0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_packed_storage/packed_storage_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage.sol b/examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage.sol new file mode 100644 index 00000000..03d7ed92 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage.sol @@ -0,0 +1,15 @@ +contract C { + uint x; + uint y; + function setX(uint a) public returns (uint _x) { + x = a; + _x = x; + } + function setY(uint a) public returns (uint _y) { + y = a; + _y = y; + } +} +// ---- +// setX(uint256): 6 -> 6 +// setY(uint256): 2 -> 2 diff --git a/examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage_standard_input.json b/examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage_standard_input.json new file mode 100644 index 00000000..144633f5 --- /dev/null +++ b/examples/test/semanticTests/viaYul_storage_simple_storage/simple_storage_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "packed_storage.sol": { + "content": "contract C {\n uint16 x;\n bytes1 y;\n uint16 z;\n function f(uint8 a) public returns (uint _x) {\n x = a;\n y = bytes1(uint8(x) + 1);\n z = uint8(y) + 1;\n x = z + 1;\n _x = x;\n }\n}\n// ----\n// f(uint8): 6 -> 9\n" + }, + "dirty_storage_dynamic_array.sol": { + "content": "contract C {\n uint8[] s;\n function f() public returns (bool correct) {\n s.push();\n assembly {\n mstore(0, s.slot)\n sstore(keccak256(0, 0x20), 257)\n }\n uint8 x = s[0];\n uint r;\n assembly {\n r := x\n }\n correct = (s[0] == 0x01) && (r == 0x01);\n }\n}\n// ----\n// f() -> true\n" + }, + "dirty_storage_bytes.sol": { + "content": "contract C {\n bytes b;\n function f() public returns (bool correct) {\n assembly {\n sstore(b.slot, or(\"deadbeef\", 0x08))\n }\n bytes1 s = b[3];\n uint r;\n assembly {\n r := s\n }\n correct = r == (0x64 << 248);\n }\n}\n// ----\n// f() -> true\n" + }, + "simple_storage.sol": { + "content": "contract C {\n uint x;\n uint y;\n function setX(uint a) public returns (uint _x) {\n x = a;\n _x = x;\n }\n function setY(uint a) public returns (uint _y) {\n y = a;\n _y = y;\n }\n}\n// ----\n// setX(uint256): 6 -> 6\n// setY(uint256): 2 -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_string_format/string_format.sol b/examples/test/semanticTests/viaYul_string_format/string_format.sol new file mode 100644 index 00000000..5869ea2e --- /dev/null +++ b/examples/test/semanticTests/viaYul_string_format/string_format.sol @@ -0,0 +1,11 @@ +contract C { + function f1() external pure returns (string memory) { return "abcabc"; } + function f2() external pure returns (string memory) { return "abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?"; } + function g() external pure returns (bytes32) { return "abcabc"; } + function h() external pure returns (bytes4) { return 0xcafecafe; } +} +// ---- +// f1() -> 0x20, 6, left(0x616263616263) +// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728 +// g() -> left(0x616263616263) +// h() -> left(0xcafecafe) diff --git a/examples/test/semanticTests/viaYul_string_format/string_format_standard_input.json b/examples/test/semanticTests/viaYul_string_format/string_format_standard_input.json new file mode 100644 index 00000000..64e4a1ab --- /dev/null +++ b/examples/test/semanticTests/viaYul_string_format/string_format_standard_input.json @@ -0,0 +1,76 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_string_literals/string_literals.sol b/examples/test/semanticTests/viaYul_string_literals/string_literals.sol new file mode 100644 index 00000000..985d2635 --- /dev/null +++ b/examples/test/semanticTests/viaYul_string_literals/string_literals.sol @@ -0,0 +1,27 @@ +contract C { + function short_dyn() public pure returns (string memory x) { + x = "abc"; + } + function long_dyn() public pure returns (string memory x) { + x = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"; + } + function short_bytes_dyn() public pure returns (bytes memory x) { + x = "abc"; + } + function long_bytes_dyn() public pure returns (bytes memory x) { + x = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"; + } + function bytesNN() public pure returns (bytes3 x) { + x = "abc"; + } + function bytesNN_padded() public pure returns (bytes4 x) { + x = "abc"; + } +} +// ---- +// short_dyn() -> 0x20, 3, "abc" +// long_dyn() -> 0x20, 80, "12345678901234567890123456789012", "34567890123456789012345678901234", "5678901234567890" +// short_bytes_dyn() -> 0x20, 3, "abc" +// long_bytes_dyn() -> 0x20, 80, "12345678901234567890123456789012", "34567890123456789012345678901234", "5678901234567890" +// bytesNN() -> 0x6162630000000000000000000000000000000000000000000000000000000000 +// bytesNN_padded() -> 0x6162630000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/viaYul_string_literals/string_literals_standard_input.json b/examples/test/semanticTests/viaYul_string_literals/string_literals_standard_input.json new file mode 100644 index 00000000..6d33add7 --- /dev/null +++ b/examples/test/semanticTests/viaYul_string_literals/string_literals_standard_input.json @@ -0,0 +1,217 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + }, + "define_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint x, uint y, uint z) {\n (uint c, uint b, uint a) = f();\n (x, y, z) = (a, b, c);\n }\n function h() public pure returns (uint) {\n (,,uint a) = f();\n return a;\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "struct_member_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint[] b;\n uint c;\n }\n\n S s;\n constructor() {\n s.a = 42;\n s.b.push(1);\n s.b.push(2);\n s.b.push(3);\n s.c = 21;\n }\n\n function f(S memory m) public pure returns (uint, uint[] memory, uint) {\n return (m.a, m.b, m.c);\n }\n function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]);\n }\n function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]);\n }\n function h() external view returns (uint, uint, uint, uint, uint, uint) {\n return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3\n// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3\n// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17\n// h() -> 42, 3, 21, 1, 2, 3\n" + }, + "local_tuple_assignment.sol": { + "content": "contract C {\n uint public x = 17;\n function f(uint a1, uint a2) public returns (uint r1, uint r2) {\n (uint b1, uint b2) = (a1, a2);\n (r1, x, r2) = (b1, b2, b2);\n }\n function g() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], m[2]) = (1, x, 3);\n return (m[2], m[1], m[0]);\n }\n function h() public returns (uint a, uint b, uint c) {\n uint256[3] memory m;\n (m[0], m[1], , m[2], m[0]) = (1, x, 3, 4, 42);\n return (m[2], m[1], m[0]);\n }\n function i() public returns (uint a, uint b, uint c, uint d) {\n (a) = 42;\n (((((b))))) = 23;\n c = (((17)));\n (((d))) = (13);\n }\n}\n// ----\n// x() -> 17\n// f(uint256,uint256): 23, 42 -> 23, 42\n// x() -> 42\n// g() -> 3, 42, 1\n// h() -> 4, 42, 1\n// i() -> 42, 23, 17, 13\n" + }, + "string_literals.sol": { + "content": "contract C {\n function short_dyn() public pure returns (string memory x) {\n x = \"abc\";\n }\n function long_dyn() public pure returns (string memory x) {\n x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n }\n function short_bytes_dyn() public pure returns (bytes memory x) {\n x = \"abc\";\n }\n function long_bytes_dyn() public pure returns (bytes memory x) {\n x = \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\";\n }\n function bytesNN() public pure returns (bytes3 x) {\n x = \"abc\";\n }\n function bytesNN_padded() public pure returns (bytes4 x) {\n x = \"abc\";\n }\n}\n// ----\n// short_dyn() -> 0x20, 3, \"abc\"\n// long_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// short_bytes_dyn() -> 0x20, 3, \"abc\"\n// long_bytes_dyn() -> 0x20, 80, \"12345678901234567890123456789012\", \"34567890123456789012345678901234\", \"5678901234567890\"\n// bytesNN() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n// bytesNN_padded() -> 0x6162630000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_struct_member_access/struct_member_access.sol b/examples/test/semanticTests/viaYul_struct_member_access/struct_member_access.sol new file mode 100644 index 00000000..a2d9a02f --- /dev/null +++ b/examples/test/semanticTests/viaYul_struct_member_access/struct_member_access.sol @@ -0,0 +1,38 @@ +pragma abicoder v2; + +contract C { + struct S { + uint a; + uint[] b; + uint c; + } + + S s; + constructor() { + s.a = 42; + s.b.push(1); + s.b.push(2); + s.b.push(3); + s.c = 21; + } + + function f(S memory m) public pure returns (uint, uint[] memory, uint) { + return (m.a, m.b, m.c); + } + function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) { + return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]); + } + function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) { + return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]); + } + function h() external view returns (uint, uint, uint, uint, uint, uint) { + return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]); + } +} +// ==== +// EVMVersion: >homestead +// ---- +// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3 +// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3 +// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17 +// h() -> 42, 3, 21, 1, 2, 3 diff --git a/examples/test/semanticTests/viaYul_struct_member_access/struct_member_access_standard_input.json b/examples/test/semanticTests/viaYul_struct_member_access/struct_member_access_standard_input.json new file mode 100644 index 00000000..7d0326ff --- /dev/null +++ b/examples/test/semanticTests/viaYul_struct_member_access/struct_member_access_standard_input.json @@ -0,0 +1,211 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + }, + "delete.sol": { + "content": "contract C {\n\tfunction internal_func() internal pure returns (int8)\n\t{\n\t\treturn 1;\n\t}\n\tfunction call_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\treturn func() == internal_func();\n\t}\n\tfunction call_deleted_internal_func() public pure returns (bool ret)\n\t{\n\t\tfunction() internal pure returns(int8) func = internal_func;\n\n\t\tdelete func;\n\n\t\treturn func() == internal_func();\n\t}\n}\n// ----\n// call_deleted_internal_func() -> FAILURE, hex\"4e487b71\", 0x51\n// call_internal_func() -> true\n" + }, + "assert.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function fail() public pure returns (bool x) {\n x = true;\n assert(false);\n }\n function succeed() public pure returns (bool x) {\n x = true;\n assert(true);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// fail() -> FAILURE, hex\"4e487b71\", 0x01\n// succeed() -> true\n" + }, + "function_address.sol": { + "content": "contract C {\n function f() external returns (address) {\n return this.f.address;\n }\n function g() external returns (bool) {\n return this.f.address == address(this);\n }\n function h(function() external a) public returns (address) {\n return a.address;\n }\n}\n// ----\n// f() -> 0xc06afe3a8444fc0004668591e8306bfb9968e79e\n// g() -> true\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> 0x1122334400112233445566778899AABBCCDDEEFF\n" + }, + "local_bool_assignment.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n }\n}\n// ----\n// f(bool): true -> true\n" + }, + "if.sol": { + "content": "contract C {\n function f(bool condition) public returns (uint x) {\n x = 23;\n if (condition)\n x = 42;\n }\n function g(bool condition) public returns (uint x) {\n x = 0;\n if (condition)\n x = 42;\n else\n x = 23;\n }\n function h(bool condition) public returns (uint x) {\n if (condition)\n return 42;\n x = 23;\n }\n function i(bool condition) public returns (uint x) {\n if (condition)\n x = 10;\n else\n return 23;\n x = 42;\n }\n function j(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n if (a + b < 10)\n x = a;\n else\n x = b;\n y = 100;\n }\n function k(uint a, uint b) public returns (uint x, uint y) {\n x = 42;\n do {\n if (a + b < 10)\n {\n if (a == b)\n {\n x = 99; y = 99;\n break;\n }\n else\n {\n x = a;\n }\n }\n else\n {\n x = b;\n if (a != b)\n y = 17;\n else\n y = 13;\n break;\n }\n y = 100;\n } while(false);\n }\n}\n// ----\n// f(bool): 0 -> 23\n// f(bool): 1 -> 42\n// g(bool): 0 -> 23\n// g(bool): 1 -> 42\n// h(bool): 0 -> 23\n// h(bool): 1 -> 42\n// i(bool): 0 -> 23\n// i(bool): 1 -> 42\n// j(uint256,uint256): 1, 3 -> 1, 100\n// j(uint256,uint256): 3, 1 -> 3, 100\n// j(uint256,uint256): 10, 23 -> 23, 100\n// j(uint256,uint256): 23, 10 -> 10, 100\n// k(uint256,uint256): 1, 3 -> 1, 100\n// k(uint256,uint256): 3, 1 -> 3, 100\n// k(uint256,uint256): 3, 3 -> 99, 99\n// k(uint256,uint256): 10, 23 -> 23, 17\n// k(uint256,uint256): 23, 10 -> 10, 17\n// k(uint256,uint256): 23, 23 -> 23, 13\n" + }, + "short_circuit.sol": { + "content": "contract C {\n function or(uint x) public returns (bool t, uint y) {\n t = (x == 0 || ((x = 8) > 0));\n y = x;\n }\n function and(uint x) public returns (bool t, uint y) {\n t = (x == 0 && ((x = 8) > 0));\n y = x;\n }\n}\n// ----\n// or(uint256): 0 -> true, 0\n// and(uint256): 0 -> true, 8\n// or(uint256): 1 -> true, 8\n// and(uint256): 1 -> false, 1\n" + }, + "detect_mod_zero.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a % b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a % b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 1\n// f(uint256,uint256): 10, 2 -> 0\n// f(uint256,uint256): 11, 2 -> 1\n// f(uint256,uint256): 2, 2 -> 0\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(uint8,uint8): 10, 3 -> 1\n// g(uint8,uint8): 10, 2 -> 0\n// g(uint8,uint8): 11, 2 -> 1\n// g(uint8,uint8): 2, 2 -> 0\n// g(uint8,uint8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(uint8,uint8): 0, 1 -> 0\n" + }, + "detect_mul_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a * b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a * b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 30\n// f(uint256,uint256): -1, 1 -> -1\n// f(uint256,uint256): -1, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> -2\n// f(uint256,uint256): 2, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -2\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x0100000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x0100000000000000000000000000000000, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000\n// f(uint256,uint256): 0x0100000000000000000000000000000001, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> -1\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000001 -> -1\n// f(uint256,uint256): 0x0100000000000000000000000000000002, 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 0x0100000000000000000000000000000002 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): -1, 0 -> 0\n// f(uint256,uint256): 0, -1 -> 0\n// g(uint8,uint8): 5, 6 -> 30\n// g(uint8,uint8): 0x80, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x7F, 2 -> 254\n// g(uint8,uint8): 2, 0x7F -> 254\n// g(uint8,uint8): 0x10, 0x10 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x0F, 0x11 -> 0xFF\n// g(uint8,uint8): 0x0F, 0x12 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0x12, 0x0F -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 0xFF, 0 -> 0\n// g(uint8,uint8): 0, 0xFF -> 0\n" + }, + "mapping_enum_key_getter.sol": { + "content": "pragma abicoder v2;\ncontract test {\n enum E { A, B, C }\n mapping(E => uint8) public table;\n function set(E k, uint8 v) public {\n table[k] = v;\n }\n}\n// ----\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0xa1 ->\n// table(uint8): 0 -> 0\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x00, 0xef ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0xa1\n// table(uint8): 0xa7 -> FAILURE\n// set(uint8,uint8): 0x01, 0x05 ->\n// table(uint8): 0 -> 0xef\n// table(uint8): 0x01 -> 0x05\n// table(uint8): 0xa7 -> FAILURE\n" + }, + "exp_literals.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ====\n// compileViaYul: true\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 256 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_uint_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_int_max(uint256): 2 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_5(uint256): 111 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_minus_5(uint256): 110 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 32 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp.sol": { + "content": "contract C {\n function f(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint256,uint256): 0, 0 -> 1\n// f(uint256,uint256): 0, 1 -> 0x00\n// f(uint256,uint256): 0, 2 -> 0x00\n// f(uint256,uint256): 1, 0 -> 1\n// f(uint256,uint256): 1, 1 -> 1\n// f(uint256,uint256): 1, 2 -> 1\n// f(uint256,uint256): 2, 0 -> 1\n// f(uint256,uint256): 2, 1 -> 2\n// f(uint256,uint256): 2, 2 -> 4\n// f(uint256,uint256): 7, 63 -> 174251498233690814305510551794710260107945042018748343\n// f(uint256,uint256): 128, 2 -> 0x4000\n" + }, + "assign_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint a, uint b, uint c) {\n (c, b, a) = f();\n }\n function h() public pure returns (uint a) {\n (,,a) = f();\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "detect_sub_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a - b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a - b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> -1\n// f(int256,int256): -2, 1 -> -3\n// f(int256,int256): -2, 2 -> -4\n// f(int256,int256): 2, -2 -> 4\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): -5, -6 -> 1\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -15 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, -16 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 15, 0x8000000000000000000000000000000000000000000000000000000000000010 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 16, 0x8000000000000000000000000000000000000000000000000000000000000010 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> -1\n// g(int8,int8): -2, 1 -> -3\n// g(int8,int8): -2, 2 -> -4\n// g(int8,int8): 2, -2 -> 4\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): -5, -6 -> 1\n// g(int8,int8): 126, -1 -> 127\n// g(int8,int8): 1, -126 -> 127\n// g(int8,int8): 127, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, 1 -> -128\n// g(int8,int8): -1, 127 -> -128\n// g(int8,int8): -127, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, 127 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_variable_without_init.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint x;\n return x;\n }\n}\n// ----\n// f() -> 0\n" + }, + "return_and_convert.sol": { + "content": "contract C {\n function f() public pure returns (uint) {\n uint8 b;\n assembly { b := 0xffff }\n return b;\n }\n}\n// ----\n// f() -> 255\n" + }, + "exp_neg_overflow.sol": { + "content": "contract C {\n function f(int8 x, uint y) public returns (int) {\n return x**y;\n }\n function g(int256 x, uint y) public returns (int) {\n return x**y;\n }\n}\n// ----\n// f(int8,uint256): 2, 6 -> 64\n// f(int8,uint256): 2, 7 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -2, 6 -> 64\n// f(int8,uint256): -2, 7 -> -128\n// f(int8,uint256): -2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 7, 2 -> 0x31\n// f(int8,uint256): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 2 -> 0x31\n// f(int8,uint256): -7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 127, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 0 -> 1\n// f(int8,uint256): -128, 1 -> -128\n// f(int8,uint256): -128, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -128, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -11, 2 -> 121\n// f(int8,uint256): -12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): 12, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int8,uint256): -5, 3 -> -125\n// f(int8,uint256): -6, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -7, 90 -> 11450477594321044359340126713545146077054004823284978858214566372120240027249\n// g(int256,uint256): -7, 91 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int256,uint256): -63, 42 -> 3735107253208426854890677539053540390278853997836851167913009474475553834369\n// g(int256,uint256): -63, 43 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "local_address_assignment.sol": { + "content": "contract C {\n function f(address a) public pure returns (address x) {\n address b = a;\n x = b;\n }\n}\n// ----\n// f(address): 0x1234 -> 0x1234\n" + }, + "comparison_functions.sol": { + "content": "contract C {\n\t// If these two functions are identical, the optimiser\n\t// on the old codegen path can deduplicate them, and breaking the test.\n\tfunction internal1() internal pure returns (bool) {\n\t\treturn true;\n\t}\n\tfunction internal2() internal pure returns (bool) {\n\t\treturn false;\n\t}\n\n\tfunction equal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 == internal1;\n\t\tdiff = internal1 == internal2;\n\t\tinv = internal1 == invalid;\n\t}\n\n\tfunction unequal() public pure returns (bool same, bool diff, bool inv) {\n\t\tfunction() internal pure returns (bool) invalid;\n\t\tdelete invalid;\n\t\tsame = internal1 != internal1;\n\t\tdiff = internal1 != internal2;\n\t\tinv = internal1 != invalid;\n\t}\n}\n// ----\n// equal() -> true, false, false\n// unequal() -> false, true, true\n" + }, + "dirty_memory_static_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[1] memory m;\n assembly {\n mstore(m, 257)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x01) && (r == 0x01);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "return_storage_pointers.sol": { + "content": "contract C {\n\tuint[] arr1;\n\tuint[][] arr2;\n\tfunction f() internal returns (uint[] storage ptr1, uint[][] storage ptr2) {\n\t\tptr1 = arr1;\n\t\tptr2 = arr2;\n\t}\n\tfunction g() public returns (uint, uint) {\n\t\treturn (arr1.length, arr2.length);\n\t}\n\n}\n// ----\n// g() -> 0, 0\n" + }, + "dirty_memory_int32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n int32 x = int32(uint32(m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0xdeadbeef15dead) && (r == (((2 ** 224 - 1) << 32) | 0xef15dead));\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "exp_overflow.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 2, 7 -> 0x80\n// f(uint8,uint8): 2, 8 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 15, 2 -> 225\n// f(uint8,uint8): 6, 3 -> 0xd8\n// f(uint8,uint8): 7, 2 -> 0x31\n// f(uint8,uint8): 7, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 7, 4 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 31 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint8,uint8): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 1 -> 0x0200000000000000000000000000000000\n// g(uint256,uint256): 0x100000000000000000000000000000010, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 0x200000000000000000000000000000000, 3 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 31 -> 400631961586894742455537928461950192806830589109049416147172451019287109375\n// g(uint256,uint256): 255, 32 -> -13630939032658036097408813250890608687528184442832962921928608997994916749311\n// g(uint256,uint256): 255, 33 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 255, 131 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 31 -> 575719427506838823084316385994930914701079543089399988096291424922125729792\n// g(uint256,uint256): 258, 37 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint256,uint256): 258, 131 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "assert_and_require.sol": { + "content": "contract C {\n function f(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n assert(b);\n }\n function f2(bool a) public pure returns (bool x) {\n bool b = a;\n x = b;\n require(b);\n }\n}\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE, hex\"4e487b71\", 0x01\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE\n" + }, + "define_tuple_from_function_call.sol": { + "content": "contract C {\n function f() public pure returns (uint, uint, uint) {\n return (1, 2, 3);\n }\n function g() public pure returns (uint x, uint y, uint z) {\n (uint c, uint b, uint a) = f();\n (x, y, z) = (a, b, c);\n }\n function h() public pure returns (uint) {\n (,,uint a) = f();\n return a;\n }\n}\n// ----\n// g() -> 3, 2, 1\n// h() -> 3\n" + }, + "struct_member_access.sol": { + "content": "pragma abicoder v2;\n\ncontract C {\n struct S {\n uint a;\n uint[] b;\n uint c;\n }\n\n S s;\n constructor() {\n s.a = 42;\n s.b.push(1);\n s.b.push(2);\n s.b.push(3);\n s.c = 21;\n }\n\n function f(S memory m) public pure returns (uint, uint[] memory, uint) {\n return (m.a, m.b, m.c);\n }\n function g(S calldata c) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c.a, c.b.length, c.c, c.b[0], c.b[1], c.b[2]);\n }\n function g2(S calldata c1, S calldata c2) external pure returns (uint, uint, uint, uint, uint, uint) {\n return (c1.a, c1.c, c2.a, c2.b.length, c2.c, c2.b[0]);\n }\n function h() external view returns (uint, uint, uint, uint, uint, uint) {\n return (s.a, s.b.length, s.c, s.b[0], s.b[1], s.b[2]);\n }\n}\n// ====\n// EVMVersion: >homestead\n// ----\n// f((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 0x60, 21, 3, 1, 2, 3\n// g((uint256,uint256[],uint256)): 0x20, 42, 0x60, 21, 3, 1, 2, 3 -> 42, 3, 21, 1, 2, 3\n// g2((uint256,uint256[],uint256),(uint256,uint256[],uint256)): 0x40, 0x0120, 42, 0x60, 21, 2, 1, 2, 3, 7, 0x80, 9, 0, 1, 17 -> 42, 21, 7, 1, 9, 17\n// h() -> 42, 3, 21, 1, 2, 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order.sol b/examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order.sol new file mode 100644 index 00000000..e1a1689b --- /dev/null +++ b/examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order.sol @@ -0,0 +1,12 @@ +contract C { + uint256 x; + uint256 y; + function set(uint256 v) public returns (uint256) { x = v; return v; } + function f() public returns (uint256, uint256) { + (y, y, y) = (set(1), set(2), set(3)); + assert(y == 1 && x == 3); + return (x, y); + } +} +// ---- +// f() -> 3, 1 diff --git a/examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order_standard_input.json b/examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order_standard_input.json new file mode 100644 index 00000000..502f9423 --- /dev/null +++ b/examples/test/semanticTests/viaYul_tuple_evaluation_order/tuple_evaluation_order_standard_input.json @@ -0,0 +1,106 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes.sol b/examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes.sol new file mode 100644 index 00000000..d8e64071 --- /dev/null +++ b/examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes.sol @@ -0,0 +1,76 @@ +contract C { + function conv(bytes25 a) public pure returns (bytes32) { + // truncating and widening + return ~bytes32(bytes16(~a)); + } + + function upcast(bytes25 a) public pure returns (bytes32) { + // implicit widening is allowed + return ~a; + } + + function downcast(bytes25 a) public pure returns (bytes12) { + // truncating cast must be explicit + return bytes12(~a); + } + + function r_b32() public pure returns (bytes32) { + return ~bytes32(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00"); + } + function r_b25() public pure returns (bytes25) { + return ~bytes25(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff"); + } + function r_b16() public pure returns (bytes16) { + return ~bytes16(hex"ff00ff00ff00ff00ff00ff00ff00ff00"); + } + function r_b8() public pure returns (bytes8) { + return ~bytes8(hex"ff00ff00ff00ff00"); + } + function r_b4() public pure returns (bytes4) { + return ~bytes4(hex"ff00ff00"); + } + function r_b1() public pure returns (bytes1) { + return ~bytes1(hex"55"); + } + + function a_b32() public pure returns (bytes32) { + bytes32 r = ~bytes32(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00"); + return r; + } + function a_b25() public pure returns (bytes25) { + bytes25 r = ~bytes25(hex"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff"); + return r; + } + function a_b16() public pure returns (bytes16) { + bytes16 r = ~bytes16(hex"ff00ff00ff00ff00ff00ff00ff00ff00"); + return r; + } + function a_b8() public pure returns (bytes8) { + bytes8 r = ~bytes8(hex"ff00ff00ff00ff00"); + return r; + } + function a_b4() public pure returns (bytes4) { + bytes4 r = ~bytes4(hex"ff00ff00"); + return r; + } + function a_b1() public pure returns (bytes1) { + bytes1 r = ~bytes1(hex"55"); + return r; + } +} +// ---- +// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff +// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000 +// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000 +// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff +// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000 +// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000 +// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000 +// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000 +// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000 +// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff +// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000 +// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000 +// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000 +// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000 +// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000 diff --git a/examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes_standard_input.json b/examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes_standard_input.json new file mode 100644 index 00000000..654f3597 --- /dev/null +++ b/examples/test/semanticTests/viaYul_unary_fixedbytes/unary_fixedbytes_standard_input.json @@ -0,0 +1,136 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + }, + "unary_fixedbytes.sol": { + "content": "contract C {\n\tfunction conv(bytes25 a) public pure returns (bytes32) {\n\t\t// truncating and widening\n\t\treturn ~bytes32(bytes16(~a));\n\t}\n\n\tfunction upcast(bytes25 a) public pure returns (bytes32) {\n\t\t// implicit widening is allowed\n\t\treturn ~a;\n\t}\n\n\tfunction downcast(bytes25 a) public pure returns (bytes12) {\n\t\t// truncating cast must be explicit\n\t\treturn bytes12(~a);\n\t}\n\n\tfunction r_b32() public pure returns (bytes32) {\n\t\treturn ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b25() public pure returns (bytes25) {\n\t\treturn ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t}\n\tfunction r_b16() public pure returns (bytes16) {\n\t\treturn ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t}\n\tfunction r_b8() public pure returns (bytes8) {\n\t\treturn ~bytes8(hex\"ff00ff00ff00ff00\");\n\t}\n\tfunction r_b4() public pure returns (bytes4) {\n\t\treturn ~bytes4(hex\"ff00ff00\");\n\t}\n\tfunction r_b1() public pure returns (bytes1) {\n\t\treturn ~bytes1(hex\"55\");\n\t}\n\n\tfunction a_b32() public pure returns (bytes32) {\n\t\tbytes32 r = ~bytes32(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b25() public pure returns (bytes25) {\n\t\tbytes25 r = ~bytes25(hex\"ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\");\n\t\treturn r;\n\t}\n\tfunction a_b16() public pure returns (bytes16) {\n\t\tbytes16 r = ~bytes16(hex\"ff00ff00ff00ff00ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b8() public pure returns (bytes8) {\n\t\tbytes8 r = ~bytes8(hex\"ff00ff00ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b4() public pure returns (bytes4) {\n\t\tbytes4 r = ~bytes4(hex\"ff00ff00\");\n\t\treturn r;\n\t}\n\tfunction a_b1() public pure returns (bytes1) {\n\t\tbytes1 r = ~bytes1(hex\"55\");\n\t\treturn r;\n\t}\n}\n// ----\n// conv(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ffffffffffffffffffffffffffffffff\n// upcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// downcast(bytes25): left(0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff) -> 0xff00ff00ff00ff00ff00ff0000000000000000000000000000000000000000\n// r_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// r_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// r_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// r_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// r_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// r_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n// a_b32() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff\n// a_b25() -> 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff0000000000000000\n// a_b16() -> 0xff00ff00ff00ff00ff00ff00ff00ff00000000000000000000000000000000\n// a_b8() -> 0xff00ff00ff00ff000000000000000000000000000000000000000000000000\n// a_b4() -> 0xff00ff00000000000000000000000000000000000000000000000000000000\n// a_b1() -> 0xaa00000000000000000000000000000000000000000000000000000000000000\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_unary_operations/unary_operations.sol b/examples/test/semanticTests/viaYul_unary_operations/unary_operations.sol new file mode 100644 index 00000000..17d8dad0 --- /dev/null +++ b/examples/test/semanticTests/viaYul_unary_operations/unary_operations.sol @@ -0,0 +1,136 @@ +contract C { + function preincr_u8(uint8 a) public pure returns (uint8) { + return ++a + a; + } + function postincr_u8(uint8 a) public pure returns (uint8) { + return a++ + a; + } + function predecr_u8(uint8 a) public pure returns (uint8) { + return --a + a; + } + function postdecr_u8(uint8 a) public pure returns (uint8) { + return a-- + a; + } + function preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) { + ret1 = ++a; + ret2 = a; + } + function postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) { + ret1 = a++; + ret2 = a; + } + function predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) { + ret1 = --a; + ret2 = a; + } + function postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) { + ret1 = a--; + ret2 = a; + } + function preincr(uint a) public pure returns (uint) { + return ++a + a; + } + function postincr(uint a) public pure returns (uint) { + return a++ + a; + } + function predecr(uint a) public pure returns (uint) { + return --a + a; + } + function postdecr(uint a) public pure returns (uint) { + return a-- + a; + } + function not(bool a) public pure returns (bool) + { + return !a; + } + function bitnot(int256 a) public pure returns (int256) + { + return ~a; + } + function bitnot_u8(uint8 a) public pure returns (uint256 ret) + { + a = ~a; + assembly { + // Tests that the lower bit parts are cleaned up + ret := a + } + } + function bitnot_s8() public pure returns (int256 ret) + { + int8 a; + assembly { + a := 0x9C + } + + a = ~a; + + assembly { + // Tests that the lower bit parts are cleaned up + ret := a + } + } + function negate(int256 a) public pure returns (int256) + { + return -a; + } + function negate_s8(int8 a) public pure returns (int8) + { + return -a; + } + function negate_s16(int16 a) public pure returns (int16) + { + return -a; + } +} +// ==== +// compileViaYul: true +// ---- +// preincr_s8(int8): 128 -> FAILURE +// postincr_s8(int8): 128 -> FAILURE +// preincr_s8(int8): 127 -> FAILURE, hex"4e487b71", 0x11 +// postincr_s8(int8): 127 -> FAILURE, hex"4e487b71", 0x11 +// preincr_s8(int8): 126 -> 127, 127 +// postincr_s8(int8): 126 -> 126, 127 +// predecr_s8(int8): -128 -> FAILURE, hex"4e487b71", 0x11 +// postdecr_s8(int8): -128 -> FAILURE, hex"4e487b71", 0x11 +// predecr_s8(int8): -127 -> -128, -128 +// postdecr_s8(int8): -127 -> -127, -128 +// preincr_s8(int8): -5 -> -4, -4 +// postincr_s8(int8): -5 -> -5, -4 +// predecr_s8(int8): -5 -> -6, -6 +// postdecr_s8(int8): -5 -> -5, -6 +// preincr_u8(uint8): 255 -> FAILURE, hex"4e487b71", 0x11 +// postincr_u8(uint8): 255 -> FAILURE, hex"4e487b71", 0x11 +// preincr_u8(uint8): 254 -> FAILURE, hex"4e487b71", 0x11 +// postincr_u8(uint8): 254 -> FAILURE, hex"4e487b71", 0x11 +// predecr_u8(uint8): 0 -> FAILURE, hex"4e487b71", 0x11 +// postdecr_u8(uint8): 0 -> FAILURE, hex"4e487b71", 0x11 +// predecr_u8(uint8): 1 -> 0 +// postdecr_u8(uint8): 1 -> 1 +// preincr_u8(uint8): 2 -> 6 +// postincr_u8(uint8): 2 -> 5 +// predecr_u8(uint8): 2 -> 2 +// postdecr_u8(uint8): 2 -> 3 +// preincr(uint256): 2 -> 6 +// postincr(uint256): 2 -> 5 +// predecr(uint256): 2 -> 2 +// postdecr(uint256): 2 -> 3 +// not(bool): true -> false +// not(bool): false -> true +// bitnot(int256): 5 -> -6 +// bitnot(int256): 10 -> -11 +// bitnot(int256): 0 -> -1 +// bitnot(int256): -100 -> 99 +// bitnot_u8(uint8): 100 -> 155 +// bitnot_s8() -> 99 +// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex"4e487b71", 0x11 +// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967 +// negate(int256): 0 -> 0 +// negate(int256): 1 -> -1 +// negate(int256): -1 -> 1 +// negate_s8(int8): -128 -> FAILURE, hex"4e487b71", 0x11 +// negate_s8(int8): -138 -> FAILURE +// negate_s8(int8): -127 -> 127 +// negate_s8(int8): 127 -> -127 +// negate_s16(int16): -32768 -> FAILURE, hex"4e487b71", 0x11 +// negate_s16(int16): -32767 -> 32767 diff --git a/examples/test/semanticTests/viaYul_unary_operations/unary_operations_standard_input.json b/examples/test/semanticTests/viaYul_unary_operations/unary_operations_standard_input.json new file mode 100644 index 00000000..bc99af40 --- /dev/null +++ b/examples/test/semanticTests/viaYul_unary_operations/unary_operations_standard_input.json @@ -0,0 +1,133 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + }, + "dirty_memory_struct.sol": { + "content": "contract C {\n struct S {\n uint8[] m;\n }\n function f() public pure returns (bool correct) {\n S memory s;\n s.m = new uint8[](1);\n assembly {\n mstore(add(s, 64), 257)\n }\n uint8 x = s.m[0];\n uint r;\n assembly {\n r := x\n }\n correct = r == 0x01;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "simple_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n a := 1\n b := 2\n c := 3\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 6\n" + }, + "function_pointers.sol": { + "content": "contract C {\n\tfunction f() public {\n\t\tfunction() internal returns (uint) _f;\n\t\t_f();\n\t}\n\tfunction g() public {\n\t\tfunction() external returns (uint) _g;\n\t\t_g();\n\t}\n\tfunction h1() internal returns (function() internal returns (uint) _h) {}\n\tfunction h2() public {\n\t\th1()();\n\t}\n\tfunction k1() internal returns (function() external returns (uint) _k) {}\n\tfunction k2() public {\n\t\tk1()();\n\t}\n}\n// ----\n// f() -> FAILURE, hex\"4e487b71\", 0x51\n// g() -> FAILURE\n// h2() -> FAILURE, hex\"4e487b71\", 0x51\n// k2() -> FAILURE\n" + }, + "tuple_evaluation_order.sol": { + "content": "contract C {\n uint256 x;\n uint256 y;\n function set(uint256 v) public returns (uint256) { x = v; return v; }\n function f() public returns (uint256, uint256) {\n (y, y, y) = (set(1), set(2), set(3));\n assert(y == 1 && x == 3);\n return (x, y);\n }\n}\n// ----\n// f() -> 3, 1\n" + }, + "dirty_memory_uint32.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint256[1] memory m;\n assembly {\n mstore(m, 0xdeadbeef15dead)\n }\n uint32 x = uint32(m[0]);\n uint r;\n assembly {\n r := x\n }\n correct = (r == 0xef15dead) && (m[0] == 0xdeadbeef15dead);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_mod_zero_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a % b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a % b;\n }\n}\n// ----\n// f(int256,int256): 10, 3 -> 1\n// f(int256,int256): 10, 2 -> 0\n// f(int256,int256): 11, 2 -> 1\n// f(int256,int256): -10, 3 -> -1\n// f(int256,int256): 10, -3 -> 1\n// f(int256,int256): -10, -3 -> -1\n// f(int256,int256): 2, 2 -> 0\n// f(int256,int256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(int256,int256): 0, 1 -> 0\n// f(int256,int256): 0, -1 -> 0\n// g(int8,int8): 10, 3 -> 1\n// g(int8,int8): 10, 2 -> 0\n// g(int8,int8): 11, 2 -> 1\n// g(int8,int8): -10, 3 -> -1\n// g(int8,int8): 10, -3 -> 1\n// g(int8,int8): -10, -3 -> -1\n// g(int8,int8): 2, 2 -> 0\n// g(int8,int8): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): 0, 1 -> 0\n// g(int8,int8): 0, -1 -> 0\n// g(int8,int8): -128, -128 -> 0\n// g(int8,int8): -128, 127 -> -1\n" + }, + "detect_add_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a + b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a + b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 11\n// f(uint256,uint256): -2, 1 -> -1\n// f(uint256,uint256): -2, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(uint256,uint256): 2, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 128, 64 -> 192\n// g(uint8,uint8): 128, 127 -> 255\n// g(uint8,uint8): 128, 128 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "exp_various.sol": { + "content": "contract C {\n function f(uint8 x, uint8 y) public returns (uint) {\n return x**y;\n }\n function g(uint x, uint y) public returns (uint) {\n return x**y;\n }\n}\n// ----\n// f(uint8,uint8): 0, 0 -> 1\n// f(uint8,uint8): 0, 1 -> 0x00\n// f(uint8,uint8): 0, 2 -> 0x00\n// f(uint8,uint8): 0, 3 -> 0x00\n// f(uint8,uint8): 1, 0 -> 1\n// f(uint8,uint8): 1, 1 -> 1\n// f(uint8,uint8): 1, 2 -> 1\n// f(uint8,uint8): 1, 3 -> 1\n// f(uint8,uint8): 2, 0 -> 1\n// f(uint8,uint8): 2, 1 -> 2\n// f(uint8,uint8): 2, 2 -> 4\n// f(uint8,uint8): 2, 3 -> 8\n// f(uint8,uint8): 3, 0 -> 1\n// f(uint8,uint8): 3, 1 -> 3\n// f(uint8,uint8): 3, 2 -> 9\n// f(uint8,uint8): 3, 3 -> 0x1b\n// f(uint8,uint8): 10, 0 -> 1\n// f(uint8,uint8): 10, 1 -> 0x0a\n// f(uint8,uint8): 10, 2 -> 100\n// g(uint256,uint256): 0, 0 -> 1\n// g(uint256,uint256): 0, 1 -> 0x00\n// g(uint256,uint256): 0, 2 -> 0x00\n// g(uint256,uint256): 0, 3 -> 0x00\n// g(uint256,uint256): 1, 0 -> 1\n// g(uint256,uint256): 1, 1 -> 1\n// g(uint256,uint256): 1, 2 -> 1\n// g(uint256,uint256): 1, 3 -> 1\n// g(uint256,uint256): 2, 0 -> 1\n// g(uint256,uint256): 2, 1 -> 2\n// g(uint256,uint256): 2, 2 -> 4\n// g(uint256,uint256): 2, 3 -> 8\n// g(uint256,uint256): 3, 0 -> 1\n// g(uint256,uint256): 3, 1 -> 3\n// g(uint256,uint256): 3, 2 -> 9\n// g(uint256,uint256): 3, 3 -> 0x1b\n// g(uint256,uint256): 10, 10 -> 10000000000\n// g(uint256,uint256): 10, 77 -> -15792089237316195423570985008687907853269984665640564039457584007913129639936\n// g(uint256,uint256): 256, 2 -> 0x010000\n// g(uint256,uint256): 256, 31 -> 0x0100000000000000000000000000000000000000000000000000000000000000\n" + }, + "smoke_test.sol": { + "content": "contract C {\n}\n// ====\n// allowNonExistingFunctions: true\n// ----\n// f() -> FAILURE\n" + }, + "mapping_getters.sol": { + "content": "contract test {\n mapping(uint256 => uint256) public m1;\n mapping(uint256 => mapping(uint256 => uint256)) public m2;\n function set(uint256 k, uint256 v) public {\n m1[k] = v;\n }\n function set(uint256 k1, uint256 k2, uint256 v) public {\n m2[k1][k2] = v;\n }\n}\n// ----\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0xa1 ->\n// m1(uint256): 0 -> 0\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x00, 0xef ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0xa1\n// m1(uint256): 0xa7 -> 0\n// set(uint256,uint256): 0x01, 0x05 ->\n// m1(uint256): 0 -> 0xef\n// m1(uint256): 0x01 -> 0x05\n// m1(uint256): 0xa7 -> 0\n// m2(uint256,uint256): 0, 0 -> 0\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0\n// set(uint256,uint256,uint256): 0xa7, 0x01, 0x23\n// m2(uint256,uint256): 0, 0x01 -> 0\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n// set(uint256,uint256,uint256): 0, 0x01, 0xef\n// m2(uint256,uint256): 0, 0x01 -> 0xef\n// m2(uint256,uint256): 0xa7, 0 -> 0\n// m2(uint256,uint256): 0xa7, 0x01 -> 0x23\n" + }, + "detect_sub_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a - b;\n }\n function g(uint8 a, uint8 b) public pure returns (uint8 x) {\n x = a - b;\n }\n}\n// ----\n// f(uint256,uint256): 6, 5 -> 1\n// f(uint256,uint256): 6, 6 -> 0\n// f(uint256,uint256): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n// g(uint8,uint8): 6, 5 -> 1\n// g(uint8,uint8): 6, 6 -> 0\n// g(uint8,uint8): 5, 6 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "function_selector.sol": { + "content": "contract C {\n function f() external returns (bytes4) {\n return this.f.selector;\n }\n function h(function() external a) public returns (bytes4) {\n return a.selector;\n }\n}\n// ----\n// f() -> left(0x26121ff0)\n// h(function): left(0x1122334400112233445566778899AABBCCDDEEFF42424242) -> left(0x42424242)\n" + }, + "unary_operations.sol": { + "content": "contract C {\n\tfunction preincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr_u8(uint8 a) public pure returns (uint8) {\n\t\treturn a-- + a;\n\t}\n\tfunction preincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = ++a;\n\t\tret2 = a;\n\t}\n\tfunction postincr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a++;\n\t\tret2 = a;\n\t}\n\tfunction predecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = --a;\n\t\tret2 = a;\n\t}\n\tfunction postdecr_s8(int8 a) public pure returns (int8 ret1, int8 ret2) {\n\t\tret1 = a--;\n\t\tret2 = a;\n\t}\n\tfunction preincr(uint a) public pure returns (uint) {\n\t\treturn ++a + a;\n\t}\n\tfunction postincr(uint a) public pure returns (uint) {\n\t\treturn a++ + a;\n\t}\n\tfunction predecr(uint a) public pure returns (uint) {\n\t\treturn --a + a;\n\t}\n\tfunction postdecr(uint a) public pure returns (uint) {\n\t\treturn a-- + a;\n\t}\n\tfunction not(bool a) public pure returns (bool)\n\t{\n\t\treturn !a;\n\t}\n\tfunction bitnot(int256 a) public pure returns (int256)\n\t{\n\t\treturn ~a;\n\t}\n\tfunction bitnot_u8(uint8 a) public pure returns (uint256 ret)\n\t{\n\t\ta = ~a;\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction bitnot_s8() public pure returns (int256 ret)\n\t{\n\t\tint8 a;\n\t\tassembly {\n\t\t\ta := 0x9C\n\t\t}\n\n\t\ta = ~a;\n\n\t\tassembly {\n\t\t\t// Tests that the lower bit parts are cleaned up\n\t\t\tret := a\n\t\t}\n\t}\n\tfunction negate(int256 a) public pure returns (int256)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s8(int8 a) public pure returns (int8)\n\t{\n\t\treturn -a;\n\t}\n\tfunction negate_s16(int16 a) public pure returns (int16)\n\t{\n\t\treturn -a;\n\t}\n}\n// ====\n// compileViaYul: true\n// ----\n// preincr_s8(int8): 128 -> FAILURE\n// postincr_s8(int8): 128 -> FAILURE\n// preincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_s8(int8): 127 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_s8(int8): 126 -> 127, 127\n// postincr_s8(int8): 126 -> 126, 127\n// predecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_s8(int8): -127 -> -128, -128\n// postdecr_s8(int8): -127 -> -127, -128\n// preincr_s8(int8): -5 -> -4, -4\n// postincr_s8(int8): -5 -> -5, -4\n// predecr_s8(int8): -5 -> -6, -6\n// postdecr_s8(int8): -5 -> -5, -6\n// preincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 255 -> FAILURE, hex\"4e487b71\", 0x11\n// preincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// postincr_u8(uint8): 254 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// postdecr_u8(uint8): 0 -> FAILURE, hex\"4e487b71\", 0x11\n// predecr_u8(uint8): 1 -> 0\n// postdecr_u8(uint8): 1 -> 1\n// preincr_u8(uint8): 2 -> 6\n// postincr_u8(uint8): 2 -> 5\n// predecr_u8(uint8): 2 -> 2\n// postdecr_u8(uint8): 2 -> 3\n// preincr(uint256): 2 -> 6\n// postincr(uint256): 2 -> 5\n// predecr(uint256): 2 -> 2\n// postdecr(uint256): 2 -> 3\n// not(bool): true -> false\n// not(bool): false -> true\n// bitnot(int256): 5 -> -6\n// bitnot(int256): 10 -> -11\n// bitnot(int256): 0 -> -1\n// bitnot(int256): -100 -> 99\n// bitnot_u8(uint8): 100 -> 155\n// bitnot_s8() -> 99\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819968 -> FAILURE, hex\"4e487b71\", 0x11\n// negate(int256): -57896044618658097711785492504343953926634992332820282019728792003956564819967 -> 57896044618658097711785492504343953926634992332820282019728792003956564819967\n// negate(int256): 0 -> 0\n// negate(int256): 1 -> -1\n// negate(int256): -1 -> 1\n// negate_s8(int8): -128 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s8(int8): -138 -> FAILURE\n// negate_s8(int8): -127 -> 127\n// negate_s8(int8): 127 -> -127\n// negate_s16(int16): -32768 -> FAILURE, hex\"4e487b71\", 0x11\n// negate_s16(int16): -32767 -> 32767\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm.sol b/examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm.sol new file mode 100644 index 00000000..b440d8e1 --- /dev/null +++ b/examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm.sol @@ -0,0 +1,21 @@ +contract C { + function f() public pure returns (uint32 x) { + uint32 a; + uint32 b; + uint32 c; + assembly { + function myAwesomeFunction(param) -> returnMe { + let localVar := 10 + returnMe := add(localVar, param) + } + let abc := sub(10, a) + let xyz := 20 + a := abc + b := myAwesomeFunction(30) + c := xyz + } + x = a + b + c; + } +} +// ---- +// f() -> 70 diff --git a/examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm_standard_input.json b/examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm_standard_input.json new file mode 100644 index 00000000..79821463 --- /dev/null +++ b/examples/test/semanticTests/viaYul_various_inline_asm/various_inline_asm_standard_input.json @@ -0,0 +1,94 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + }, + "empty_return_corrupted_free_memory_pointer.sol": { + "content": "contract C {\n function f() public {\n assembly{ mstore(0x40, sub(0, 1)) }\n }\n}\n// ----\n// f() ->\n" + }, + "mapping_string_key.sol": { + "content": "contract C {\n\tmapping (string => uint) map;\n\tfunction set(string memory s) public {\n\t\tmap[s];\n\t}\n}\n// ----\n// set(string): 0x20, 32, \"01234567890123456789012345678901\" ->\n" + }, + "comparison.sol": { + "content": "contract C {\n function f(address a) public pure returns (bool) {\n return a == address(0);\n }\n function g() public pure returns (bool) {\n return bytes3(\"abc\") == bytes4(\"abc\");\n }\n function lt(uint a, uint b) public pure returns (bool) {\n return a < b;\n }\n function slt(int a, int b) public pure returns (bool) {\n return a < b;\n }\n function lte(uint a, uint b) public pure returns (bool) {\n return a <= b;\n }\n function slte(int a, int b) public pure returns (bool) {\n return a <= b;\n }\n function gt(uint a, uint b) public pure returns (bool) {\n return a > b;\n }\n function sgt(int a, int b) public pure returns (bool) {\n return a > b;\n }\n function gte(uint a, uint b) public pure returns (bool) {\n return a >= b;\n }\n function sgte(int a, int b) public pure returns (bool) {\n return a >= b;\n }\n function eq(uint a, uint b) public pure returns (bool) {\n return a == b;\n }\n function neq(uint a, uint b) public pure returns (bool) {\n return a != b;\n }\n}\n// ----\n// f(address): 0x1234 -> false\n// f(address): 0x00 -> true\n// g() -> true\n// lt(uint256,uint256): 4, 5 -> true\n// lt(uint256,uint256): 5, 5 -> false\n// lt(uint256,uint256): 6, 5 -> false\n// gt(uint256,uint256): 4, 5 -> false\n// gt(uint256,uint256): 5, 5 -> false\n// gt(uint256,uint256): 6, 5 -> true\n// lte(uint256,uint256): 4, 5 -> true\n// lte(uint256,uint256): 5, 5 -> true\n// lte(uint256,uint256): 6, 5 -> false\n// gte(uint256,uint256): 4, 5 -> false\n// gte(uint256,uint256): 5, 5 -> true\n// gte(uint256,uint256): 6, 5 -> true\n// eq(uint256,uint256): 4, 5 -> false\n// eq(uint256,uint256): 5, 5 -> true\n// eq(uint256,uint256): 6, 5 -> false\n// neq(uint256,uint256): 4, 5 -> true\n// neq(uint256,uint256): 5, 5 -> false\n// neq(uint256,uint256): 6, 5 -> true\n// slt(int256,int256): -1, 0 -> true\n// slt(int256,int256): 0, 0 -> false\n// slt(int256,int256): 1, 0 -> false\n// sgt(int256,int256): -1, 0 -> false\n// sgt(int256,int256): 0, 0 -> false\n// sgt(int256,int256): 1, 0 -> true\n// slte(int256,int256): -1, 0 -> true\n// slte(int256,int256): 0, 0 -> true\n// slte(int256,int256): 1, 0 -> false\n// sgte(int256,int256): -1, 0 -> false\n// sgte(int256,int256): 0, 0 -> true\n// sgte(int256,int256): 1, 0 -> true\n" + }, + "require.sol": { + "content": "contract C {\n\tfunction f(bool a) public pure returns (bool x) {\n\t\tbool b = a;\n\t\tx = b;\n\t\trequire(b);\n\t}\n\tfunction fail() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(false);\n\t}\n\tfunction succeed() public pure returns (bool x) {\n\t\tx = true;\n\t\trequire(true);\n\t}\n\tfunction f2(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\tmessage = \"fancy message!\";\n\t\trequire(a, message);\n\t}\n\tfunction f3(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\trequire(a, \"msg\");\n\t}\n\tfunction f4(bool a) public pure returns (bool x) {\n\t\tx = a;\n\t\tstring memory message;\n\t\trequire(a, message);\n\t}\n}\n// ====\n// EVMVersion: >=byzantium\n// ----\n// f(bool): true -> true\n// f(bool): false -> FAILURE\n// fail() -> FAILURE\n// succeed() -> true\n// f2(bool): true -> true\n// f2(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 14, \"fancy message!\"\n// f3(bool): true -> true\n// f3(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 3, \"msg\"\n// f4(bool): true -> true\n// f4(bool): false -> FAILURE, hex\"08c379a0\", 0x20, 0\n" + }, + "various_inline_asm.sol": { + "content": "contract C {\n function f() public pure returns (uint32 x) {\n uint32 a;\n uint32 b;\n uint32 c;\n assembly {\n function myAwesomeFunction(param) -> returnMe {\n let localVar := 10\n returnMe := add(localVar, param)\n }\n let abc := sub(10, a)\n let xyz := 20\n a := abc\n b := myAwesomeFunction(30)\n c := xyz\n }\n x = a + b + c;\n }\n}\n// ----\n// f() -> 70\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/viaYul_virtual_functions/virtual_functions.sol b/examples/test/semanticTests/viaYul_virtual_functions/virtual_functions.sol new file mode 100644 index 00000000..798f90ff --- /dev/null +++ b/examples/test/semanticTests/viaYul_virtual_functions/virtual_functions.sol @@ -0,0 +1,30 @@ +contract X { + function f() public returns (uint x) { + x = g(); + } + function g() public virtual returns (uint x) { + x = 2; + } +} +contract C is X { + function f1() public returns (uint x) { + // direct call + x = g(); + } + function f2() public returns (uint x) { + // call via base + x = f(); + } + function f3() public returns (uint x) { + // explicit call via base + //x = super.g(); + } + function g() public override returns (uint x) { + x = 3; + } +} +// ---- +// f() -> 3 +// f1() -> 3 +// f2() -> 3 +// g() -> 3 diff --git a/examples/test/semanticTests/viaYul_virtual_functions/virtual_functions_standard_input.json b/examples/test/semanticTests/viaYul_virtual_functions/virtual_functions_standard_input.json new file mode 100644 index 00000000..b822ad6a --- /dev/null +++ b/examples/test/semanticTests/viaYul_virtual_functions/virtual_functions_standard_input.json @@ -0,0 +1,79 @@ +{ + "language": "Solidity", + "sources": { + "return.sol": { + "content": "contract C {\n function f() public pure returns (uint x) {\n return 7;\n x = 3;\n }\n}\n// ----\n// f() -> 7\n" + }, + "detect_add_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a + b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a + b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 11\n// f(int256,int256): -2, 1 -> -1\n// f(int256,int256): -2, 2 -> 0\n// f(int256,int256): 2, -2 -> 0\n// f(int256,int256): -5, -6 -> -11\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0, 0x0F -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x0F, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n// f(int256,int256): 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 1, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000001, -1 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000001 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 5, 6 -> 11\n// g(int8,int8): -2, 1 -> -1\n// g(int8,int8): -2, 2 -> 0\n// g(int8,int8): 2, -2 -> 0\n// g(int8,int8): -5, -6 -> -11\n// g(int8,int8): 126, 1 -> 127\n// g(int8,int8): 1, 126 -> 127\n// g(int8,int8): 127, 1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 1, 127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> -128\n// g(int8,int8): -1, -127 -> -128\n// g(int8,int8): -127, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -127 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -128, 0 -> -128\n// g(int8,int8): 0, -128 -> -128\n" + }, + "function_entry_checks.sol": { + "content": "contract C {\n function f() public returns (uint) {\n }\n function g(uint x, uint y) public returns (uint) {\n }\n function h() public payable returns (uint) {\n }\n function i(bytes32 b) public returns (bytes32) {\n }\n function j(bool b) public returns (bool) {\n }\n function k(bytes32 b) public returns (bytes32) {\n }\n function s() public returns (uint256[] memory) {\n }\n function t(uint) public pure {\n }\n}\n// ----\n// f() -> 0\n// g(uint256,uint256): 1, -2 -> 0\n// h(), 1 ether -> 0\n// i(bytes32), 1 ether: 2 -> FAILURE\n// i(bytes32): 2 -> 0\n// j(bool): true -> false\n// k(bytes32): 0x31 -> 0x00\n// s(): hex\"4200ef\" -> 0x20, 0\n// t(uint256) -> FAILURE\n" + }, + "copy_struct_invalid_ir_bug.sol": { + "content": "contract C {\n\tstruct Struct {\n\t\tfunction () external el;\n\t}\n\tStruct[] array;\n\tint externalCalled = 0;\n\n\tfunction ext() external {\n\t\texternalCalled++;\n\t}\n\n\tfunction f() public {\n\t\tarray.push(Struct(this.ext));\n\t\tarray.push(array[0]);\n\n\t\tarray[0].el();\n\t\tarray[1].el();\n\n\t\tassert(externalCalled == 2);\n\t}\n}\n// ----\n// f() ->\n// gas irOptimized: 113117\n// gas legacy: 112888\n// gas legacyOptimized: 112580\n" + }, + "exp_literals_success.sol": { + "content": "contract C {\n function exp_2(uint y) public returns (uint) {\n return 2**y;\n }\n function exp_minus_2(uint y) public returns (int) {\n return (-2)**y;\n }\n\n function exp_uint_max(uint y) public returns (uint) {\n return (2**256 - 1)**y;\n }\n function exp_int_max(uint y) public returns (int) {\n return ((-2)**255)**y;\n }\n\n function exp_5(uint y) public returns (uint) {\n return 5**y;\n }\n function exp_minus_5(uint y) public returns (int) {\n return (-5)**y;\n }\n\n function exp_256(uint y) public returns (uint) {\n return 256**y;\n }\n function exp_minus_256(uint y) public returns (int) {\n return (-256)**y;\n }\n\n}\n// ----\n// exp_2(uint256): 255 -> 57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_minus_2(uint256): 255 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_uint_max(uint256): 1 -> 115792089237316195423570985008687907853269984665640564039457584007913129639935\n// exp_int_max(uint256): 1 -> -57896044618658097711785492504343953926634992332820282019728792003956564819968\n// exp_5(uint256): 110 -> 77037197775489434122239117703397092741524065928615527809597551822662353515625\n// exp_minus_5(uint256): 109 -> -15407439555097886824447823540679418548304813185723105561919510364532470703125\n// exp_256(uint256): 31 -> 452312848583266388373324160190187140051835877600158453279131187530910662656\n// exp_minus_256(uint256): 31 -> -452312848583266388373324160190187140051835877600158453279131187530910662656\n" + }, + "dirty_calldata_struct.sol": { + "content": "pragma abicoder v2;\ncontract C {\n struct S {\n uint16[] m;\n }\n function f(S calldata s) public pure returns (bool correct) {\n int8 x = int8(int16(s.m[0]));\n uint r;\n assembly {\n r := x\n }\n correct = r == 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80;\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f((uint16[])): 0x20, 0x20, 0x01, 0x0180 -> true\n" + }, + "simple_assignment.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x, uint y) {\n x = a;\n y = b;\n }\n}\n// ----\n// f(uint256,uint256): 5, 6 -> 5, 6\n" + }, + "dirty_memory_dynamic_array.sol": { + "content": "contract C {\n function f() public pure returns (bool correct) {\n uint8[] memory m = new uint8[](1);\n assembly {\n mstore(add(m, 32), 258)\n }\n uint8 x = m[0];\n uint r;\n assembly {\n r := x\n }\n correct = (m[0] == 0x02) && (r == 0x02);\n }\n}\n// ====\n// compileViaYul: true\n// ----\n// f() -> true\n" + }, + "detect_div_overflow.sol": { + "content": "contract C {\n function f(uint a, uint b) public pure returns (uint x) {\n x = a / b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a / b;\n }\n function h(uint256 a, uint256 b) public pure returns (uint256 x) {\n x = a / b;\n }\n}\n// ----\n// f(uint256,uint256): 10, 3 -> 3\n// f(uint256,uint256): 1, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// f(uint256,uint256): 0, 1 -> 0\n// g(int8,int8): -10, 3 -> -3\n// g(int8,int8): -10, -3 -> 3\n// g(int8,int8): -10, 0 -> FAILURE, hex\"4e487b71\", 0x12\n// g(int8,int8): -128, 1 -> -128\n// g(int8,int8): -128, -2 -> 64\n// g(int8,int8): -128, 2 -> -64\n// g(int8,int8): -128, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -127, -1 -> 127\n// h(uint256,uint256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> 0\n" + }, + "detect_mul_overflow_signed.sol": { + "content": "contract C {\n function f(int a, int b) public pure returns (int x) {\n x = a * b;\n }\n function g(int8 a, int8 b) public pure returns (int8 x) {\n x = a * b;\n }\n function h(int160 a, int160 b) public pure returns (int160 x) {\n x = a * b;\n }\n}\n// ----\n// f(int256,int256): 5, 6 -> 30\n// f(int256,int256): -1, 1 -> -1\n// f(int256,int256): -1, 2 -> -2 # positive, positive #\n// f(int256,int256): 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -1, 0x8000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0x8000000000000000000000000000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000000, -2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0x4000000000000000000000000000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): 2, 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000000 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): -2, 0x4000000000000000000000000000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, 2 -> 0x8000000000000000000000000000000000000000000000000000000000000000\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000001, -2 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): 0xC000000000000000000000000000000000000000000000000000000000000000, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000001 -> 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// f(int256,int256): -2, 0xC000000000000000000000000000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11 # small type #\n// g(int8,int8): 5, 6 -> 30\n// g(int8,int8): -1, 1 -> -1\n// g(int8,int8): -1, 2 -> -2 # positive, positive #\n// g(int8,int8): 63, 2 -> 126\n// g(int8,int8): 64, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, 63 -> 126\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 2, 64 -> FAILURE, hex\"4e487b71\", 0x11 # positive, negative #\n// g(int8,int8): 64, -2 -> -128\n// g(int8,int8): 65, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): 2, -64 -> -128\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): 2, -65 -> FAILURE, hex\"4e487b71\", 0x11 # negative, positive #\n// g(int8,int8): -2, 64 -> -128\n// g(int8,int8): -2, 65 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -64, 2 -> -128\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -65, 2 -> FAILURE, hex\"4e487b71\", 0x11 # negative, negative #\n// g(int8,int8): -63, -2 -> 126\n// g(int8,int8): -64, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// g(int8,int8): -2, -63 -> 126\n// g(int8,int8): -2, -64 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 1 -> -1\n// h(int160,int160): 1, -1 -> -1\n// h(int160,int160): -1, 2 -> -2\n// h(int160,int160): 2, -1 -> -2\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): -1, 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000, -1 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000000, -2 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000000 -> 0xFFFFFFFFFFFFFFFFFFFFFFFF8000000000000000000000000000000000000000\n// h(int160,int160): -2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, -2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000004000000000000000000000000000000000000001, 2 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n// h(int160,int160): 0x0000000000000000000000003FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 2 -> 0x0000000000000000000000007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE\n// h(int160,int160): 2, 0x0000000000000000000000004000000000000000000000000000000000000001 -> FAILURE, hex\"4e487b71\", 0x11\n" + }, + "msg_sender.sol": { + "content": "contract C {\n function test() public view returns (bool) {\n address x;\n assembly { x := caller() }\n return x == msg.sender;\n }\n}\n// ----\n// test() -> true\n" + }, + "keccak.sol": { + "content": "contract C {\n function keccak1() public pure returns (bytes32) {\n\t\treturn keccak256(\"123\");\n }\n function keccak2() public pure returns (bytes32) {\n\t\tbytes memory a = \"123\";\n\t\treturn keccak256(a);\n }\n}\n// ----\n// keccak1() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n// keccak2() -> 0x64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107\n" + }, + "negation_bug.sol": { + "content": "contract C {\n\tfunction f() public pure {\n\t\t-(int8(0));\n\t\tunchecked {\n\t\t\t// Used to incorrectly use the checked unary negation function and revert.\n\t\t\t(-(type(int8).min));\n\t\t}\n\t}\n}\n// ----\n// f() ->\n" + }, + "memory_struct_allow.sol": { + "content": "contract C {\n struct S {\n uint256 a;\n uint256 b;\n }\n\n function f() public pure returns (uint256 a, uint256 b){\n assembly {\n // Make free memory dirty to check that the struct allocation cleans it up again.\n let freeMem := mload(0x40)\n mstore(freeMem, 42)\n mstore(add(freeMem, 32), 42)\n }\n S memory s;\n return (s.a, s.b);\n }\n}\n// ----\n// f() -> 0, 0\n" + }, + "string_format.sol": { + "content": "contract C {\n\tfunction f1() external pure returns (string memory) { return \"abcabc\"; }\n\tfunction f2() external pure returns (string memory) { return \"abcabc`~12345677890- _=+!@#$%^&*()[{]}|;:',<.>?\"; }\n\tfunction g() external pure returns (bytes32) { return \"abcabc\"; }\n\tfunction h() external pure returns (bytes4) { return 0xcafecafe; }\n}\n// ----\n// f1() -> 0x20, 6, left(0x616263616263)\n// f2() -> 32, 47, 44048183223289766195424279195050628400112610419087780792899004030957505095210, 18165586057823232067963737336409268114628061002662705707816940456850361417728\n// g() -> left(0x616263616263)\n// h() -> left(0xcafecafe)\n" + }, + "virtual_functions.sol": { + "content": "contract X {\n function f() public returns (uint x) {\n x = g();\n }\n function g() public virtual returns (uint x) {\n x = 2;\n }\n}\ncontract C is X {\n function f1() public returns (uint x) {\n // direct call\n x = g();\n }\n function f2() public returns (uint x) {\n // call via base\n x = f();\n }\n function f3() public returns (uint x) {\n // explicit call via base\n //x = super.g();\n }\n function g() public override returns (uint x) {\n x = 3;\n }\n}\n// ----\n// f() -> 3\n// f1() -> 3\n// f2() -> 3\n// g() -> 3\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls.sol b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls.sol new file mode 100644 index 00000000..28705ee4 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls.sol @@ -0,0 +1,18 @@ +contract Base { + function f() public returns (uint256 i) { + return g(); + } + + function g() internal virtual returns (uint256 i) { + return 1; + } +} + + +contract Derived is Base { + function g() internal override returns (uint256 i) { + return 2; + } +} +// ---- +// f() -> 2 diff --git a/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls_standard_input.json b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls_standard_input.json new file mode 100644 index 00000000..d6b0d60a --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls/internal_virtual_function_calls_standard_input.json @@ -0,0 +1,40 @@ +{ + "language": "Solidity", + "sources": { + "internal_virtual_function_calls_through_dispatch.sol": { + "content": "contract Base {\n function f() internal returns (uint256 i) {\n function() internal returns (uint256) ptr = g;\n return ptr();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n\n function h() public returns (uint256 i) {\n return f();\n }\n}\n// ----\n// h() -> 2\n" + }, + "virtual_override_changing_mutability_public.sol": { + "content": "contract A {\n function f() internal virtual {\n mutableWithViewOverride();\n mutableWithPureOverride();\n viewWithPureOverride();\n }\n\n function mutableWithViewOverride() public virtual {}\n function mutableWithPureOverride() public virtual {}\n function viewWithPureOverride() public view virtual {}\n}\n\ncontract C is A {\n function run() public {\n f();\n }\n\n function mutableWithViewOverride() public view override {}\n function mutableWithPureOverride() public pure override {}\n function viewWithPureOverride() public pure override {}\n}\n// ----\n// run() ->\n" + }, + "internal_virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch.sol b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch.sol new file mode 100644 index 00000000..d8334304 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch.sol @@ -0,0 +1,23 @@ +contract Base { + function f() internal returns (uint256 i) { + function() internal returns (uint256) ptr = g; + return ptr(); + } + + function g() internal virtual returns (uint256 i) { + return 1; + } +} + + +contract Derived is Base { + function g() internal override returns (uint256 i) { + return 2; + } + + function h() public returns (uint256 i) { + return f(); + } +} +// ---- +// h() -> 2 diff --git a/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch_standard_input.json b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch_standard_input.json new file mode 100644 index 00000000..a22fef91 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_internal_virtual_function_calls_through_dispatch/internal_virtual_function_calls_through_dispatch_standard_input.json @@ -0,0 +1,34 @@ +{ + "language": "Solidity", + "sources": { + "internal_virtual_function_calls_through_dispatch.sol": { + "content": "contract Base {\n function f() internal returns (uint256 i) {\n function() internal returns (uint256) ptr = g;\n return ptr();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n\n function h() public returns (uint256 i) {\n return f();\n }\n}\n// ----\n// h() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls.sol b/examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls.sol new file mode 100644 index 00000000..ea543a78 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls.sol @@ -0,0 +1,19 @@ +contract Base { + function f() public returns (uint256 i) { + return g(); + } + + function g() public virtual returns (uint256 i) { + return 1; + } +} + + +contract Derived is Base { + function g() public override returns (uint256 i) { + return 2; + } +} +// ---- +// g() -> 2 +// f() -> 2 diff --git a/examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls_standard_input.json b/examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls_standard_input.json new file mode 100644 index 00000000..b976b591 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_function_calls/virtual_function_calls_standard_input.json @@ -0,0 +1,43 @@ +{ + "language": "Solidity", + "sources": { + "internal_virtual_function_calls_through_dispatch.sol": { + "content": "contract Base {\n function f() internal returns (uint256 i) {\n function() internal returns (uint256) ptr = g;\n return ptr();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n\n function h() public returns (uint256 i) {\n return f();\n }\n}\n// ----\n// h() -> 2\n" + }, + "virtual_override_changing_mutability_public.sol": { + "content": "contract A {\n function f() internal virtual {\n mutableWithViewOverride();\n mutableWithPureOverride();\n viewWithPureOverride();\n }\n\n function mutableWithViewOverride() public virtual {}\n function mutableWithPureOverride() public virtual {}\n function viewWithPureOverride() public view virtual {}\n}\n\ncontract C is A {\n function run() public {\n f();\n }\n\n function mutableWithViewOverride() public view override {}\n function mutableWithPureOverride() public pure override {}\n function viewWithPureOverride() public pure override {}\n}\n// ----\n// run() ->\n" + }, + "internal_virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// f() -> 2\n" + }, + "virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() public virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() public override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// g() -> 2\n// f() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments.sol b/examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments.sol new file mode 100644 index 00000000..55a50a5c --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments.sol @@ -0,0 +1,31 @@ +contract BaseBase { + uint256 m_a; + + constructor(uint256 a) { + m_a = a; + } + + function overridden() public virtual returns (uint256 r) { + return 1; + } + + function g() public returns (uint256 r) { + return overridden(); + } +} + + +contract Base is BaseBase(BaseBase.g()) {} + + +contract Derived is Base { + function getA() public returns (uint256 r) { + return m_a; + } + + function overridden() public override returns (uint256 r) { + return 2; + } +} +// ---- +// getA() -> 2 diff --git a/examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments_standard_input.json b/examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments_standard_input.json new file mode 100644 index 00000000..f0030593 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_function_usage_in_constructor_arguments/virtual_function_usage_in_constructor_arguments_standard_input.json @@ -0,0 +1,46 @@ +{ + "language": "Solidity", + "sources": { + "internal_virtual_function_calls_through_dispatch.sol": { + "content": "contract Base {\n function f() internal returns (uint256 i) {\n function() internal returns (uint256) ptr = g;\n return ptr();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n\n function h() public returns (uint256 i) {\n return f();\n }\n}\n// ----\n// h() -> 2\n" + }, + "virtual_override_changing_mutability_public.sol": { + "content": "contract A {\n function f() internal virtual {\n mutableWithViewOverride();\n mutableWithPureOverride();\n viewWithPureOverride();\n }\n\n function mutableWithViewOverride() public virtual {}\n function mutableWithPureOverride() public virtual {}\n function viewWithPureOverride() public view virtual {}\n}\n\ncontract C is A {\n function run() public {\n f();\n }\n\n function mutableWithViewOverride() public view override {}\n function mutableWithPureOverride() public pure override {}\n function viewWithPureOverride() public pure override {}\n}\n// ----\n// run() ->\n" + }, + "internal_virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// f() -> 2\n" + }, + "virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() public virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() public override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// g() -> 2\n// f() -> 2\n" + }, + "virtual_function_usage_in_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n\n function overridden() public virtual returns (uint256 r) {\n return 1;\n }\n\n function g() public returns (uint256 r) {\n return overridden();\n }\n}\n\n\ncontract Base is BaseBase(BaseBase.g()) {}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n\n function overridden() public override returns (uint256 r) {\n return 2;\n }\n}\n// ----\n// getA() -> 2\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal.sol b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal.sol new file mode 100644 index 00000000..cee1bcdd --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal.sol @@ -0,0 +1,23 @@ +contract A { + function f() internal virtual { + mutableWithViewOverride(); + mutableWithPureOverride(); + viewWithPureOverride(); + } + + function mutableWithViewOverride() internal virtual {} + function mutableWithPureOverride() internal virtual {} + function viewWithPureOverride() internal view virtual {} +} + +contract C is A { + function run() public { + f(); + } + + function mutableWithViewOverride() internal view override {} + function mutableWithPureOverride() internal pure override {} + function viewWithPureOverride() internal pure override {} +} +// ---- +// run() -> diff --git a/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal_standard_input.json b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal_standard_input.json new file mode 100644 index 00000000..ef7f3922 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_internal/virtual_override_changing_mutability_internal_standard_input.json @@ -0,0 +1,49 @@ +{ + "language": "Solidity", + "sources": { + "internal_virtual_function_calls_through_dispatch.sol": { + "content": "contract Base {\n function f() internal returns (uint256 i) {\n function() internal returns (uint256) ptr = g;\n return ptr();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n\n function h() public returns (uint256 i) {\n return f();\n }\n}\n// ----\n// h() -> 2\n" + }, + "virtual_override_changing_mutability_public.sol": { + "content": "contract A {\n function f() internal virtual {\n mutableWithViewOverride();\n mutableWithPureOverride();\n viewWithPureOverride();\n }\n\n function mutableWithViewOverride() public virtual {}\n function mutableWithPureOverride() public virtual {}\n function viewWithPureOverride() public view virtual {}\n}\n\ncontract C is A {\n function run() public {\n f();\n }\n\n function mutableWithViewOverride() public view override {}\n function mutableWithPureOverride() public pure override {}\n function viewWithPureOverride() public pure override {}\n}\n// ----\n// run() ->\n" + }, + "internal_virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// f() -> 2\n" + }, + "virtual_function_calls.sol": { + "content": "contract Base {\n function f() public returns (uint256 i) {\n return g();\n }\n\n function g() public virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() public override returns (uint256 i) {\n return 2;\n }\n}\n// ----\n// g() -> 2\n// f() -> 2\n" + }, + "virtual_function_usage_in_constructor_arguments.sol": { + "content": "contract BaseBase {\n uint256 m_a;\n\n constructor(uint256 a) {\n m_a = a;\n }\n\n function overridden() public virtual returns (uint256 r) {\n return 1;\n }\n\n function g() public returns (uint256 r) {\n return overridden();\n }\n}\n\n\ncontract Base is BaseBase(BaseBase.g()) {}\n\n\ncontract Derived is Base {\n function getA() public returns (uint256 r) {\n return m_a;\n }\n\n function overridden() public override returns (uint256 r) {\n return 2;\n }\n}\n// ----\n// getA() -> 2\n" + }, + "virtual_override_changing_mutability_internal.sol": { + "content": "contract A {\n function f() internal virtual {\n mutableWithViewOverride();\n mutableWithPureOverride();\n viewWithPureOverride();\n }\n\n function mutableWithViewOverride() internal virtual {}\n function mutableWithPureOverride() internal virtual {}\n function viewWithPureOverride() internal view virtual {}\n}\n\ncontract C is A {\n function run() public {\n f();\n }\n\n function mutableWithViewOverride() internal view override {}\n function mutableWithPureOverride() internal pure override {}\n function viewWithPureOverride() internal pure override {}\n}\n// ----\n// run() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file diff --git a/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public.sol b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public.sol new file mode 100644 index 00000000..c3d9e60a --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public.sol @@ -0,0 +1,23 @@ +contract A { + function f() internal virtual { + mutableWithViewOverride(); + mutableWithPureOverride(); + viewWithPureOverride(); + } + + function mutableWithViewOverride() public virtual {} + function mutableWithPureOverride() public virtual {} + function viewWithPureOverride() public view virtual {} +} + +contract C is A { + function run() public { + f(); + } + + function mutableWithViewOverride() public view override {} + function mutableWithPureOverride() public pure override {} + function viewWithPureOverride() public pure override {} +} +// ---- +// run() -> diff --git a/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public_standard_input.json b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public_standard_input.json new file mode 100644 index 00000000..a6fd58c7 --- /dev/null +++ b/examples/test/semanticTests/virtualFunctions_virtual_override_changing_mutability_public/virtual_override_changing_mutability_public_standard_input.json @@ -0,0 +1,37 @@ +{ + "language": "Solidity", + "sources": { + "internal_virtual_function_calls_through_dispatch.sol": { + "content": "contract Base {\n function f() internal returns (uint256 i) {\n function() internal returns (uint256) ptr = g;\n return ptr();\n }\n\n function g() internal virtual returns (uint256 i) {\n return 1;\n }\n}\n\n\ncontract Derived is Base {\n function g() internal override returns (uint256 i) {\n return 2;\n }\n\n function h() public returns (uint256 i) {\n return f();\n }\n}\n// ----\n// h() -> 2\n" + }, + "virtual_override_changing_mutability_public.sol": { + "content": "contract A {\n function f() internal virtual {\n mutableWithViewOverride();\n mutableWithPureOverride();\n viewWithPureOverride();\n }\n\n function mutableWithViewOverride() public virtual {}\n function mutableWithPureOverride() public virtual {}\n function viewWithPureOverride() public view virtual {}\n}\n\ncontract C is A {\n function run() public {\n f();\n }\n\n function mutableWithViewOverride() public view override {}\n function mutableWithPureOverride() public pure override {}\n function viewWithPureOverride() public pure override {}\n}\n// ----\n// run() ->\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "peephole": false, + "inliner": false, + "jumpdestRemover": false, + "orderLiterals": false, + "deduplicate": false, + "cse": false, + "constantOptimizer": false + } + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "metadata", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers" + ] + } + } + } +} \ No newline at end of file